QueryList изменения подписки не работает
У меня есть QueryList
в компоненте. Я добавляю динамически другие компоненты, которые будут присутствовать в QueryList
, но если я подпишусь на changes
из QueryList
, Ничего не произошло. Я думал, что это потому, что я подписался на ngAfterViewInit
, но QueryList
является undefined
еще в ngOnInit
, Здесь у меня есть plunkr.
код:
@Component({
...
})
export class AppComponent {
@ViewChildren(ControlFactoryDirective) factories:
QueryList<ControlFactoryDirective>
ngAfterViewInit() {
this.factories.changes.subscribe(() => {
console.log('changed')
})
}
}
4 ответа
Дело в том, что список, который приходит к вам factories
недвижимость уже заселена. Таким образом, у вас просто нет возможности подписаться на его изменения до того, как он будет заполнен в первый раз. Но все изменения, которые произойдут позже, конечно же, приходят к вашему подписчику.
Вот plunkr с вашим обновленным примером - обратите внимание, что на фабриках теперь есть сеттер, который доказывает, что он предварительно заполнен (вам обычно это не нужно в реальном приложении, это для того, чтобы узнать только то, какое значение дает фреймворк)
Я думаю, что это абсолютно правильное поведение. Так в ngAfterViewInit
, переберите значения в QueryList и сделайте то же самое, что вы собираетесь сделать в подписчике:
ngAfterViewInit() {
this.processChildren(); // first call to processChildren
this.factories.changes.subscribe(_ =>
this.processChildren() // subsequent calls to processChildren
);
}
private processChildren(): void {
console.log('Processing children. Their count:', this.factories.toArray().length)
}
Вы также можете добавить
startWith(undefined)
нравится:
ngAfterViewInit() {
this.factories.changes.pipe(startWith(undefined)).subscribe(() =>
{
console.log('changed')
})
}
Это немедленно запустит обработчик подписки.
После внесения изменений в объекты в списке запросов вы должны вызвать список запросов, чтобы уведомить об изменениях.
update() {
this.factories.forEach(factory => {
console.log(factory.componentRef.instance.model.data = "alma")
// factory.()
this.factories.notifyOnChanges();
})
}
export class AppComponent {
factoryList : any = [{ id: 1,name: "abc", detail: "abc abc abc"}];
@ViewChildren(ControlFactoryDirective) factoryDirective:
QueryList<ControlFactoryDirective>
ngAfterViewInit() {
this.factoryDirective.changes.subscribe(() => {
console.log('changed')
})
}
addNewfactory(){
this.factoryList .push({ id: 11,name: "xyz", detail: "xyz xyz xyz"});
}
}
I assume that ControlFactoryDirective is used in html like below. Number of the components and used Factory objects depends on the factoryList size. When button is clicked a new Factory object will be added to the factoryList. factoryList size is changed, new ControlFactoryDirective component is added/displayed, also subscribe method will be called.
<button (click)="addNewfactory()">Add</button>
<controlfactorydirective *ngFor='let factory of factoryList'
[factory]="factory">
</controlfactorydirective >