I have two Angular components app-image-input and app-button. I use app-button in the template for app-image-input as follows.
AppButtonComponent
appButton.html
<button type="button" (click)="buttonClicked.emit()">{{label}}</button>
appButton.ts
@Component({
selector: 'app-button',
templateUrl: './appButton.html'
})
export class AppButtonComponent {
@Input()
label : string
@Input()
enabled : boolean
@Output()
buttonClicked = new EventEmitter()
}
AppImageInputComponent
appImageInput.html
<div class="take-photo">
<span>Photo</span><input type="file" accept="image/*" capture>
</div>
<hr class="hr">
<div class="inner">
<app-button class="submit" label="Submit" (buttonClicked)="submitClk()"></app-button>
<app-button label="Cancel" (buttonClicked)="cancelClk()"></app-button>
</div>
AppModule
app.module.ts
// ..... imports go here.
@NgModule({
declarations: [AppButtonComponent, AppImageInputComponent],
entryComponents: [AppButtonComponent, AppImageInputComponent],
imports: [
FormsModule,
BrowserModule,
],
providers: [],
bootstrap: []
})
export class AppModule {
ngDoBootstrap() {
}
constructor(injector: Injector) {
Array.from(new Map<Type<any>, string>([
[AppButtonComponent, 'app-button'],
[AppImageInputComponent, 'app-image-input'],
]), ([key, value]) => {
customElements.define(value, createCustomElement(key, {injector}))
})
}
}
Problem I package my app as angular elements and use in vanilla HTML/JS app. The weird behavior I am encountering has to do with the way I use my image input component.
If I do the following, I get an image component as expected.
<body>
<app-image-input></app-image-input>
</body>
</html>
However, when I do the following, buttons are duplicated.
<body>
<script>
setTimeout(() => {
var elem = document.createElement("app-image-input");
document.body.appendChild(elem);
}, 1000);
</script>
</body>
</html>
Please note that setting the timeout to something around 400 (instead of 1000) millisecs gives the correct output!!
You can find complete project here.
Also, https://stackblitz.com/edit/angular-4mgv3c thanks to Caramiriel
As mentioned above, it's rendered as an Angular component and it's also rendered as an web component too. Hence, you see it twice. Just use an custom element name that does not match the app's selector, so that you can decide whether to render the custom element version or the Angular component version.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With