I want to make a directory tree and to have access to all items regardless of the level, but @ViewChildren/@ViewQuery's QueryList is not updated when I dynamically add second level children:
import {bootstrap} from 'angular2/platform/browser';
import {Component, View, QueryList,ViewQuery, Query,ViewChildren} from 'angular2/core';
@Component({
selector: 'item',
})
@View({
template: `
<button (click)="addChild()">Add Child</button>
<ng-content></ng-content>
<div *ngFor="#child of children; #i = index">
<item> {{child.name}}</item>
</div>
`
})
export class Item {
//public children = [ { name: 'Child 1', age: 22 } ];
public children = [];
addChild() {
this.children.push({ name: 'Child' + (this.children.length + 1), age: 18 });
}
}
@Component({
selector: 'my-app'
})
@View({
directives: [Item],
template: `
<button (click)="addParent()">Add Parent</button>
<div *ngFor="#user of users; #i = index">
<item #item> {{user.name}}</item>
</div>
`
})
export class AppComponent {
public users = [
{ name: 'Parent 1', age: 22 }
];
@ViewChildren(Item, {descendants: true}) itemList: QueryList<Item>;
constructor() {}
ngAfterViewInit() {
console.log(this.itemList);
this.itemList.changes.subscribe(() => console.log(this.itemList));
}
addParent() {
this.users.push({ name: 'Parent ' + (this.users.length + 1), age: 18 });
}
}
bootstrap(AppComponent);
It is updated when I addParent(), but not updated when I addChild(). It looks like QueryList is subscribed only for top level changes. Any ideas how to make it work?
I think that it's something more general than the use of @ViewChildren
/ @ViewQuery
.
In fact, it's the way Angular2 handles the change detection. I mean updates within objects don't trigger change detection but if you update the whole reference, it does.
So you need to refactor a bit your removeDynamic
method:
addChild() {
this.children.push({ name: 'Child' + (this.children.length + 1), age: 18 });
this.children = this.children.slice();
}
addParent() {
this.users.push({ name: 'Parent ' + (this.users.length + 1), age: 18 });
this.users = this.users.slice();
}
See this answer regarding the use of the slice
method:
Here is the answer from the Angular team regarding this behavior: https://github.com/angular/angular/issues/6458.
Hope it helps you, Thierry
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