What is the preferred method of communicating between contentChildren and its 'parent'?
UPDATED: Child may not be direct parent...
Given a random list of children, wrapped by a group:
<child-group>
<div>Some other content, child may not be direct parent...</div>
<child *ngFor="let item of data$ | async;"></child>
</child-group>
The child component:
@Component({
selector: 'child',
template: '<button (click)="didSomethingTellGroup()"></button>',
styleUrls: ['child.component.scss'],
})
export class ChildComponent implements OnInit {
constructor() {
}
ngOnInit() {
}
doSomething() {
console.log('Called from group component')
}
didSomethingTellGroup() {
//EventEmitter?
//Observable?
}
}
The parent component:
@Component({
selector: 'child-group',
template: '<ng-content></ng-content>',
styleUrls: ['child-group.component.scss'],
})
export class ChildGroupComponent implements AfterContentInit {
@ContentChildren(ChildComponent) childrenList: QueryList<ChildComponent>;
constructor() {
}
ngAfterContentInit() {
//How to invoke doSomething() on all children?
childrenList...
//How can I get notification from one or all children, that it did something, or its state has changed.
childrenList...
}
}
How can I invoke a child method from ChildGroup? And how can a Child send information back to the ChildGroup?
UPDATE:
In the comments below I mentioned that when I was trying to invoke a method on the children nothing was happening. Well it turns out that I needed subscribe to the changes and wait for the children...then I was able to invoke
ngAfterContentInit()
{
this.childrenList.changes
.subscribe(list => {
list.forEach(c => c.doSomething())
}
);
}
For your child to parent scenario, an @Output event emitter is your best bet. Your child component is converting an internal action in itself ( a user clicking somewhere) into a business related event that any user of that component can listen for.
As for parent calling child, you're already most of the way there with your example. Just iterate over the QueryList and call whatever method you wish on your child components.
ngAfterContentInit() {
//How to invoke doSomething() on all children?
this.childrenList.forEach ( c => c.doSomething(); )
...
}
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