ngOnChanges не запускается, если @Input получает объект - PullRequest
2 голосов
/ 07 марта 2019

Шаблон родительского компонента:

<my-component [param]="whatever"></my-component>

Код родительского компонента:

whatever = { value1: 0, value2: 1, value3: 'foo' };

Код дочернего компонента:

@Input() public param: any;

ngOnChanges() {
  console.log('Received input: ', param);
}

Это не работает.Любое изменение в whatever будет незаметно для дочернего компонента и ngOnChanges не сработает.

Это также не сработает, если я попытаюсь использовать установщик:

@Input() set param(value) {
  console.log(value);
}

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

Очевидно, @Input() может обнаруживать только изменение структуры объекта, но не его значений.

Итак, как я могу передать объект как свойство @Input() и сделать так, чтобы дочерний компонент обнаруживал изменения значений?

Ответы [ 3 ]

2 голосов
/ 07 марта 2019

Хук жизненного цикла OnChanges запускается при изменении значения свойства @Input. В случае объекта это значение является ссылкой на объект . Если ссылка на объект не изменяется, OnChanges не срабатывает.

Возможный метод принудительного обнаружения изменений - установить новую ссылку на объект после изменения значений свойства:

this.whatever.value1 = 2;
this.whatever.value2 = 3;
this.whatever = Object.assign({}, this.whatever);

Обработчик события ngOnChanges затем можно использовать для отслеживания изменений:

ngOnChanges(changes: SimpleChanges) {
  for (let propName in changes) {
    let chng = changes[propName];
    let cur = JSON.stringify(chng.currentValue);
    console.log(propName, cur);
  }
}

В качестве альтернативы, если @Input украшает свойство метода получения / установки, изменения можно отслеживать в установщике:

private _param: Object;

@Input() get param(): Object {
  return this._param;
} 
set param(value: Object) {
  console.log("setter", value);
  this._param = value;
}

См. этот стек для демонстрации.

1 голос
/ 07 марта 2019

Обнаружение изменения угла запускается при изменении значения свойства @Input.

Таким образом, чтобы инициировать обнаружение изменений в случае объекта, вы можете передать копию объекта с использованием оператора распространения в качестве входных данных.

например someVar = {key: value} это @Input() переменная, поэтому передайте как

<app-sample [someVar]="{...someVar}" ></app-sample>

{...VARIABLE} <- вот волшебство </p>

1 голос
/ 07 марта 2019

Как это:

@Input() public param: any;
ngOnChanges(changes: SimpleChanges): void {
    // Do your check here
    console.log(changes.param.previousValue);
}

Использование изменений дает вам доступ к previousValue и currentValue.

...