Angular ngOnChanges в дочернем элементе не запускается после того, как подписка манипулирует данными

У меня проблема с ngOnChanges, который не запускается для дочернего компонента после того, как данные обрабатываются в родительском с помощью метода подписки.

В основном мой основной компонент выглядит так:

public imageGroups: IImageGroup[];
public status$: Observable<ModelStatusesModel>;


public ngOnChanges(changes: SimpleChanges): void {
  if (Boolean(this.treeData)) {
    this.imageGroups = this.treeDataService.convertImageGroups(this.treeData);
    this.status$ = this.updateStatus();
    this.status$.subscribe((status: ModelStatusesModel) => {
      this.treeDataService.updateStatus(this.imageGroups, status); // this function makes changes to this.imageGroups
      console.log('subscribe happened');
    });
  }
}

HTML:

...
<ul class="treeview-nodes-wrapper">
  <treeview-branch *ngFor="let group of (imageGroups)"
                                          [group]="group"></treeview-branch>
</ul>
...

В ветке также есть ngOnChnages:

public ngOnChanges(): void {
  this._currentNodeDisabled = this.group.isDisabled;
  console.log(this.group); //returns isDisables as true
  console.log(this.group.isDisabled); //returns false
  console.log(this._currentNodeDisabled); //returns false
}

Когда я запускаю свое приложение, в консоли появляется следующий результат:

{ ... isDisabled: true ...},
false
false
subscribe happened

Я также пытался заключить звонок внутри своей подписки в ngZone.run, но безуспешно. У вас есть идеи, как сказать angular, что ngOnChanges в дочернем элементе срабатывает?

РЕДАКТИРОВАТЬ: То, что мне подходит, - это создание свойства в родительском компоненте (public change = false;), затем переключение этого свойства внутри моего метода подписки и передача его в качестве входных данных для моих дочерних элементов. Это воспринимается как изменение. Несмотря на то, что это решает мою проблему, это больше похоже на очень хитрый способ написания кода.


person Lubos    schedule 29.07.2020    source источник
comment
Возможный дубликат из: stackoverflow.com/questions/39913255/   -  person Marc Hernández    schedule 29.07.2020
comment
@ MarcHernández Я не понимаю, как это можно применить к моей проблеме, поскольку я имею дело с совершенно другой структурой   -  person Lubos    schedule 29.07.2020


Ответы (2)


Это результат того, что ngOnChanges запускается при вводе входного значения changes, а для объектов, которые передаются по ссылке, изменение их свойств явно не меняет передаваемый объект. Решение часто состоит в том, чтобы выполнить клонирование, ... оператор распространения или переназначить свойство, которое передается в родительском [input].

Ваше решение с дополнительным вводом, которое изменяется на новое значение для запуска ngOnChanges, также работает, это своего рода обходной путь, но это веб-разработчик. просто помните, что если вы установите для свойства значение true, то снова оно не сработает, поэтому переменная count может работать лучше (это вроде хакерство).

person iamaword    schedule 29.07.2020

Выполнение клона через JSON.parse решило мою проблему более чистым способом, чем переключение переменной:

...
  this.status$.subscribe((status: ModelStatusesModel) => {
    this.treeDataService.updateStatus(this.imageGroups, status);
    triggerChange();
  });
...

private triggerChange() {
    this.imageGroups = JSON.parse(JSON.stringify(this.imageGroups));
}
person Lubos    schedule 30.07.2020