Вызывать 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()
вызывается с огромной частотой — после каждого цикла обнаружения изменений, независимо от того, где произошло изменение. Простое перемещение курсора мыши на другой вход вызывает вызов.