Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@Query behaves differently when searching TemplateRef

Tags:

angular

To begin with this behavior only happens in beta16, previous releases are working as expected.

@Query also finds the template elements of descendant elements, consider a component looking for Template elements in content;

export class Container {

    constructor(@Query(TemplateRef) templates: QueryList<TemplateRef>) {
        templates.changes.subscribe(_ => {
            console.log(templates.length);
        });
    }

}

@Component({
selector: 'my-app',
template: `<container>
             <template></template>
             <child>
                 <template></template>
             </child>
           </container>`,
directives: [Container,Child]

http://plnkr.co/edit/sANW6mfss5EvPfWpXRde

I expect "1" to be logged on console, but "2" is logged. Template of child is also found.

But replacing template element with some random component e.g. otherchild, produces the expected result;

export class Container {

    constructor(@Query(OtherChild) templates: QueryList<OtherChild>) {
        templates.changes.subscribe(_ => {
            console.log(templates.length);
        });
    }

}


@Component({
selector: 'my-app',
template: `<container>
             <otherchild></otherchild>
             <child>
                 <otherchild></otherchild>
             </child>
           </container>`,
directives: [Container,Child,OtherChild]

})

http://plnkr.co/edit/OzXjz8niAurzr6CZIoes

"1" is printed as container has only one otherchild.

So something is different with template elements causing confusion. I wonder if this is a bug or intended behavior.

like image 912
Cagatay Civici Avatar asked May 25 '26 06:05

Cagatay Civici


1 Answers

@Query() which is deprecated since a while in favor of @ContentChildren().

Hint: the result of @ContentChildren() can't be accessed in the constructor, only after ngAfterContentInit() was called.

Also descendants: true needs to be passed to not only get direct children but all descendants (this might be what has changed the @Query() - I don't know if this parameter is now available there as well)

export class Container {
  @ContentChildren(OtherChild, {descendants: true}) templates;
  ngAfterContentInit( ) {
    console.log(this.templates.length);
    this.templates.changes.subscribe(_ => {
      console.log(templates.length);
    });
  }
}

Plunker example

I can reproduce your issue with @ContentChildren() as well. This code also prints 2 but it should print 1. I assume this is a bug caused by the change to @ContentChilren() and @ViewChildren() in beta.16.

export class Container {
  @ContentChildren(TemplateRef, {descendants: false}) templates;

  ngAfterContentInit() {
    console.log(this.templates.length);
    this.templates.changes.subscribe(_ => {
      console.log(templates.length);
    });
  }
}

Plunker example

like image 70
Günter Zöchbauer Avatar answered May 26 '26 20:05

Günter Zöchbauer