ChangeDetection в Angular

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

Если я использую changeDetection: ChangeDetectionStrategy.OnPush, на ловушке жизненного цикла ngOnChanges мне нужно также проверить, существует ли currentValue? Или достаточно проверить, был ли изменен ввод?

Я могу привести вам пример, чтобы лучше понять, о чем я говорю:

Итак, как я уже упоминал, я использую changeDetection: ChangeDetectionStrategy.OnPush, и это мой ввод @Input() isInspectionReopened: boolean;, а ngOnChanges выглядит так:

ngOnChanges(changes: SimpleChanges) {
  if(changes.isInspectionReopened) {
     // do something
  }
}

Достаточно проверить changes.isInspectionReopened или мне нужно добавить changes.isInspectionReopened.currentValue?


person Sergiu Molnar    schedule 24.07.2019    source источник


Ответы (1)


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

Когда вы используете ChangeDetectionStrategy.OnPush, обычно вам вообще не следует использовать обратный вызов ngOnChanges. ChangeDetectionStrategy.OnPush влияет только на логику, которая принимает решение, когда запускать обнаружение изменений. Итак, когда isInspectionReopened prop изменяется, срабатывает обнаружение изменений, потому что это свойство '@Input', и ваш компонент html будет обновлен, если он привязан к свойству.

Но если isInspectionReopened не является свойством '@Input', например, компонент загружает значение с сервера и обновляет его, обнаружение OnPush не распознает это изменение, в отличие от стандартного обнаружения изменений. Вы можете использовать RxJs Observables с async pipe для принудительного обнаружения изменений в случае стратегии OnPush, вот пример.

Также имейте в виду, что свойства «@Input» запускают обнаружение изменений только тогда, когда они обновляются через привязку данных вашего родительского компонента. Если значение свойства «@Input» изменяется самим компонентом, обнаружение изменения не запускается.

Обнаружение изменений также запускается событиями dom компонента. Например, если вы прослушиваете событие щелчка и что-то измените в обработчике щелчка, обнаружение изменений все равно сработает из-за события.

person Valeriy Katkov    schedule 24.07.2019
comment
Хорошее объяснение! И напоследок одно: для ChangeDetectionStrategy.OnPush Angular ChangeDetection запускается только при изменении параметра Input, И это литерал (например, логическое или строковое). Он не запускается, когда что-то внутри объекта изменилось. Затем вы можете увидеть изменение в ngOnChanges, но вам придется запустить changeDetection вручную. - person dave0688; 24.07.2019
comment
@ dave0688 Да, вы правы. Более того, он запускается только тогда, когда свойство @Input изменяется привязкой данных, которая может изменить только ссылку на опору, но не внутреннее состояние. Немного обновил ответ. Если внутреннее свойство объекта может быть изменено, я делаю его наблюдаемым, и это решает проблему. В прошлом году я написал большой проект angular без обнаружения изменений вручную, я просто использовал ChangeDetectorRef только для того, чтобы вручную запускать обнаружение изменений несколько раз. - person Valeriy Katkov; 24.07.2019