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));
        }
      }
    }
}

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

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