Angular 2 - изменить соседнюю входную переменную при изменении входной переменной
Я хочу выполнить некоторые операции при изменении входных параметров. Допустим, у меня есть компонент DatePicker, который имеет type
входная переменная, и я хочу выполнить некоторые действия с другим date
переменная при изменении типа. Как это сделать?
export class DatePicker {
@Input()
date: Date;
@Output()
dateChange = new EventEmitter();
@Input()
set type(type: string) {
if (type === "today") {
this.date = new Date();
this.dateChange(this.date); // because of this change change detector will throw error
}
}
}
Ошибка: выражение изменилось после того, как оно было проверено.
1 ответ
Обновить
Angular2 вызывает эту ошибку, когда похоже, что само обнаружение изменений имеет побочные эффекты, которые вызывают изменение модели, что обычно указывает на ошибку или конструктивный недостаток, из-за которого приложения Angular2 работают неэффективно.
Чтобы скрыть такую проблему, вы можете просто включить prodMode
,
Обходной путь для изменения модели в вызове методов жизненного цикла ChangeDetectorRef.detectChanges()
чтобы сделать явным, что это изменение модели является преднамеренным
export class DatePicker {
constructor(private cdRef:ChangeDetectorRef) {}
@Input()
date: Date;
@Output()
dateChange = new EventEmitter();
@Input()
set type(type: string) {
if (type === "today") {
this.date = new Date();
this.dateChange(this.date);
this.cdRef.detectChanges();
}
}
}
оригинал
Вы можете использовать setTimeout()
setTimeout()
является методом кувалды, потому что он вызывает цикл обнаружения изменений для всего приложения.
@Input()
set type(type: string) {
if (type === "today") {
this.date = new Date();
setTimeout(() => this.dateChange(this.date));
}
}
Это необходимо, когда type
обновляется при обнаружении изменений, поскольку Angular2 не нравится, когда обнаружение изменений вызывает изменения.
Другой способ заключается в использовании ngOnChanges()
но это также называется обнаружением изменений и также нуждается в setTimeout()
Временное решение
export class DatePicker implements OnChanges {
@Input()
date: Date;
@Output()
dateChange = new EventEmitter();
@Input()
set type:string;
ngOnChanges(changes:SimpleChanges) {
if(changes['type']) {
if (type === "today") {
this.date = new Date();
setTimeout(() => this.dateChange(this.date));
}
}
}
}
Разница между этими двумя подходами заключается в том, что первый выполняет код для каждого изменения, последний - только для изменений, вызванных привязками.