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 >
Другие вопросы по тегам