Вызывать detectChanges() внутри ловушек жизненного цикла Angular2?

Что я знаю, так это то, что мы вызываем DetectChanges() для запуска локальных проверок изменений. Я видел некоторый код, который Detechanges () вызывается внутри хука ngOnChanges(change), и мне было интересно, почему кто-то хочет сделать что-то подобное? Я имею в виду, если бы обнаружение изменений не было обнаружено, ngOnChanges не был бы вызван правильно? Так зачем вызывать DetectChanges внутри тела хука?

@Directive({
    selector: "[dateDisplay]"
})
export class DateDisplayDirective {
    @Input() ngModel: Date;
    @Input() format: string;

    constructor(private _elem: ElementRef, private _change: ChangeDetectorRef) { }

    ngOnChanges(change) {
        if (change.ngModel && change.ngModel.currentValue && change.ngModel.currentValue != change.ngModel.previousValue) {
            let date = this.ngModel ? moment.utc(this.ngModel) : null;
            if (this._elem.nativeElement.value != undefined) {
                this._elem.nativeElement.value = date ? date.format(this.format) : "";
                this._change.detectChanges();
            }
        }
    }
}

1 ответ

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

не кажется хорошим местом для запуска обнаружения изменений вручную

Кроме того, форматирование значения для отображения должно выполняться в конвейере, а не в директиве, поэтому любые проблемы, которые возникли у автора этого кода с обнаружением изменений, могут быть решены, если использовать конвейер!

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

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

Из документации Angular:

ngOnChanges()

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

Обнаруживайте изменения, которые Angular не может или не будет обнаруживать самостоятельно, и реагируйте на них.

Предположим, у вас есть@Inputsв вашем компоненте, и один из них является объектом.

      export class Hero  
{
    id:string;
    name:string; 
}

@Input() hero!: Hero;
@Input() power = '';

Когда вы меняете имя героя (например, вводите его в какой-либо ввод на своей странице), обнаружение изменений не будет запущено, потому что с точки зрения Angular ссылка на объект героя не изменилась, поэтому нет необходимости запускать обнаружение изменений.

Но мы знаем, что имя изменилось, и мы хотим заставить angular отразить это изменение. Вот гдеngDoCheckможет пригодиться.

        ngDoCheck() {
    this._change.detectChanges()
  }

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

Другие вопросы по тегам