Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2: contentChildren communication

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())
            }
        );
}
like image 990
Thibs Avatar asked May 27 '26 06:05

Thibs


1 Answers

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(); ) 
   ...
}
like image 200
snorkpete Avatar answered May 30 '26 03:05

snorkpete



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!