I've a parent component which hosts a list of child components. This children are create dynamically and can be of any type.
So, what I'm doing is using an ng-container
as host in the parent component, create the child components with ComponentFactoryResolver
and then update some properties in the child component using ```(component.instance as any).id = host.id;````
Here is the code for parent component (it's a table with some rows):
<tr class="table-collapse__item" [class.active]="company === selected">
<td [attr.colspan]="getItemColspan()">
<ng-container host [id]="name" [selected]="isSelected"></ng-container>
</td>
</tr>
host
is a directive
@Directive({
selector: '[host]'
})
export class Host implements OnChanges {
@Input() id: any;
@Input() selected: boolean;
constructor(public viewRef: ViewContainerRef) {}
}
and finally how to create the components and update the properties
@ViewChildren(Host) hosts: QueryList<Host>;
constructor(private resolver: ComponentFactoryResolver,
private cd: ChangeDetectorRef) {}
ngAfterViewInit() {
if (this.hosts) {
const componentFactory = this.resolver.resolveComponentFactory(this.inner);
this.hosts.forEach((host: Host) => {
const component = host.viewRef.createComponent(componentFactory);
(component.instance as any).id = host.id;
(component.instance as any).selected = host.selected;
});
this.cd.detectChanges();
}
}
Now, my question. I need the child component to react to changes in its properties, but as its properies are not Inputs but just basic properties, I can´t use ngOnChanges inside the childComponent. So it's there a way I can subscribe from the child component to changes in the parent component?
I can use ngOnChanges in the Host directive and update the properties in the component, but how to then trigger some code in the child component?
I have a plunker to test it. When clicking on data1, data2, data3 or data4, the row below should collapse or expande.
Thanks.
Use the @Input() decorator in a child component or directive to let Angular know that a property in that component can receive its value from its parent component. It helps to remember that the data flow is from the perspective of the child component.
To pass data from child to parent component in React:Pass a function as a prop to the Child component. Call the function in the Child component and pass the data as arguments. Access the data in the function in the Parent .
We can get child component values in the parent component by creating a reference to the child component using the @ref directive in the Parent component. Using the reference instance, you can access the child component values in the parent.
Child components can't listen to changes in the parent, but you can notify them about changes by calling a method on the children instead:
components = [];
ngAfterVeiwInit() {
if (this.hosts) {
const componentFactory = this.resolver.resolveComponentFactory(this.inner);
this.hosts.forEach((host: Host) => {
const component = host.viewRef.createComponent(componentFactory);
(component.instance as any).id = host.id;
(component.instance as any).selected = host.selected;
this.components.push.components();
});
this.cd.detectChanges();
}
}
ngOnChanges() {
this.components.forEach((c) => {
c.instance.ngOnChanges(); // or any other method the child comonents have
})
}
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