2016-06-26 3 views
2

Я хочу выполнить некоторые операции при изменении входных параметров. Допустим, у меня есть компонент DatePicker, который имеет входную переменную type, и я хочу выполнить некоторые действия с другой переменной date при изменении типа. Как это сделать?Угловая 2 - изменение входной переменной соседа при изменении входной переменной

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

} 

Ошибка: Выражение изменилось после того, как он был установлен.

+0

Я предлагаю вам сделать первую дату @Input(): any; ', а затем обработать переменную ввода – AngJobs

+0

' this.dateChange (this.date); 'должно быть' this.dateChange.emit (this.date) ; '(отсутствует' emit') –

+0

у вас есть временная связь, которой следует избегать. требуется, чтобы 'date' был установлен до' type'. Либо объедините оба в одну дату: Date | string' или поместить их в объект. Даже «dateChange» должен иметь слушателя уже на месте, что звучит, как будто лучше найти другой подход. –

ответ

-3

обновление

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

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

+1

с использованием setTimeout выглядит как патч обезьяны. Тот же патч обезьяны, который мы использовали в angular1 с setTimeout и применяем. Нам нужно что-то лучше – pleerock

+0

Я слышал об этом несколько раз о 'setTimeout()'. Я не вижу проблемы с 'setTimeout()', пока другой код не зависит от определенного времени, которое нужно передать или еще не нужно передать. Все, что он делает, это запланировать изменение, которое должно произойти после завершения текущего цикла обнаружения изменений и вызвать другое изменение после изменения. –

+0

Вы можете попробовать ввести 'private cdRef: ChangeDetectorRef' и вызвать' this.cdRef.detectChanges() 'после' this.dateChange (this.date) ' –

Смежные вопросы