How to handle/provide @Input
and @Output
properties for dynamically created Components in Angular 2?
The idea is to dynamically create (in this case) the SubComponent when the createSub method is called. Forks fine, but how do I provide data for the @Input
properties in the SubComponent. Also, how to handle/subscribe to the @Output
events the SubComponent provides?
Example: (Both components are in the same NgModule)
AppComponent
@Component({
selector: 'app-root'
})
export class AppComponent {
someData: 'asdfasf'
constructor(private resolver: ComponentFactoryResolver, private location: ViewContainerRef) { }
createSub() {
const factory = this.resolver.resolveComponentFactory(SubComponent);
const ref = this.location.createComponent(factory, this.location.length, this.location.parentInjector, []);
ref.changeDetectorRef.detectChanges();
return ref;
}
onClick() {
// do something
}
}
SubComponent
@Component({
selector: 'app-sub'
})
export class SubComponent {
@Input('data') someData: string;
@Output('onClick') onClick = new EventEmitter();
}
You can easily bind it when you create the component:
createSub() {
const factory = this.resolver.resolveComponentFactory(SubComponent);
const ref = this.location.createComponent(factory, this.location.length, this.location.parentInjector, []);
ref.someData = { data: '123' }; // send data to input
ref.onClick.subscribe( // subscribe to event emitter
(event: any) => {
console.log('click');
}
)
ref.changeDetectorRef.detectChanges();
return ref;
}
Sending data is really straigthforward, just do ref.someData = data
where data
is the data you wish to send.
Getting data from output is also very easy, since it's an EventEmitter
you can simply subscribe to it and the clojure you pass in will execute whenever you emit()
a value from the component.