whiite
whiite

Reputation: 198

angular 2 | can't get child directives with @ContentChildren

I'm trying to get nested directives from a parent directive, but @ContentChildren not being populated. basically I'm building a lazy-load on images, each image is a nested directive from a parent directive


example:

parent.directive.ts:

import ...

@Directive({
    'selector': 'parentSelector'
})
export class ParentDirective implements onInit, AfterContentInit {
    @ContentChildren(ChildDirective) private items: QueryList<ChildDirective>;

    ngOnInit(): void {}

    ngAfterContentInit(): void {
        console.log(this.items, this.items.toArray()); // <---

        // call a child directive method...
        this.items.forEach((item: ChildDirective) => {
            item.makeSomething();
        });
    }
}

here, this.items wasn't populated

child.directive.ts:

import ...

@Directive({
    selector: 'childSelector'
})
export class ChildDirective {
    makeSomething(): void {
        console.log('called from ParentDirective');
    }
}

app.component.ts

import ...

@Component({
    selector: 'app',
    template: `<div>
        <some-component parentSelector [items]="itemsData"></some-component>
    </div>`
})
export class AppComponent {
    // NOTE: "itemsData" is loaded asynchronously from a service
    ...
}

property "itemsData" is loaded asynchronously from a service

some-component.component.html

<!-- 'items' was obtained from AppComponent @Input('items')
     see also: 'itemsData' on AppComponent
-->

<div *ngFor="let image of images">
    <img childSelector src="image.src">
</div>

problem is on 'some-component' cycle, since the data is loaded asynchronously, @ContentChildren is empty.

NOTE: all images are displayed on some-component

any ideas? thanks in advance.

Upvotes: 4

Views: 2607

Answers (1)

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657148

There was a bug (fixed in 2.0.1) that @ContentChildren() didn't search descendants by default. You can work around with setting it explicitly

@ContentChildren(ChildDirective, {descendants: true})

In 2.0.1 true is the default value.

Upvotes: 1

Related Questions