Дочерний метод ngOnChanges не запускается при попытке передать новый объект - PullRequest
1 голос
/ 04 апреля 2019

У меня есть родительская страница, которая передает данные user в дочерний компонент, например:

<ng-container *ngIf="leaderboard">
    <app-leaderboard-preview [user]="user" (click)="goToLeaderboard()"></app-leaderboard-preview>
</ng-container>

Родительская страница ngOnInit() подписывается на наблюдаемое, которое возвращает объект пользователя и устанавливает переменную user (я удалил другие нерелевантные запросы из combineLatest):

combineLatest([this.userQuery$]).subscribe((results) => {
  Promise.all([this.parseUser(results[4])])
})

Насколько я понимаю, ngOnChanges() не сработает, пока не будет создан новый объект, поэтому я назначаю новый пользовательский объект как новый объект для передачи компоненту app-leaderboard-preview, используя Object.assign()

  parseUser(user) {
    return new Promise((resolve) => {
      if(user) {
        this.user = Object.assign({}, user);
        resolve(user);
      } else {
        resolve(user);
      }
    })
  }

Это нормально загружает компонент, но ранжирование пользователя может измениться, поэтому, когда пользователь проводит вниз, чтобы обновить страницу, значение должно быть обновлено, но компонент не обновляется. Я использую следующий код (почти как копия, как указано выше), чтобы обновить страницу (без полной перезагрузки).

  doRefresh(event) {
    if (this.user) {
      //user
      this.userQuery$ = this.db.query$(`user/find?id=${this.user.id}`);
      combineLatest([this.userQuery$]).subscribe((results) => {
        Promise.all([this.parseUser(results[4])])
      })
  }

Который затем запускает метод parseUser для обновления объекта user, который использует app-leaderboard-preview.

Так что это должно вызвать ngOnChanges, потому что я передаю «новый» объект компоненту. Чего мне не хватает?

Ответы [ 2 ]

1 голос
/ 04 апреля 2019

Редактировать

После того, как Джордан понял, что у него есть асинхронный канал, назначающий переменную пользователя, которая отменяет его изменения в this.user.

*ngIf = user$ | async as user

Оригинальный ответ

Object.assign ({}, object) должен работать.Протестировано на Angular 7.

this.user = Object.assign({}, user);

.. или если вы используете lodash, вы можете это сделать.

this.user = _.clone(user);
this.user = _.cloneDeep(user);

https://lodash.com/docs/4.17.11#clone

https://lodash.com/docs/4.17.11#cloneDeep

Демонстрация Stackblitz: https://stackblitz.com/edit/ngonchangeswithobject

0 голосов
/ 04 апреля 2019

Я сталкивался с этой же проблемой и раньше, и мне любопытно, если кто-нибудь знает, как ее решить.

Я нашел способ использовать методы get () set () для моей входной переменной следующим образом.Это не очень хорошее решение, особенно если у вас более одной входной переменной.

  private _user: any;
  @Input()
  set user(value: any) {
    this._user = value;
    // run ngOnChanges stuff here
    this.ngOnChanges();
  }
  get user(): any {
    return this._user;
  }
...