#angular #angular2-changedetection
#angular #angular2-обнаружение изменений
Вопрос:
@input
Значение дочернего компонента не обновляет свое значение в html
, как two-way
обычно делает привязка. Вот мой код.
parent.component.html
<app-child [i]="selectedMonth" (monthChanged)="monthChanged($event)"></app-child>
monthChanged(d: Date) {
this.selectedMonth = d; // this is working as expected.
console.error(this.selectedMonth); // working...
}
child.component.html
<div>
<span (click)="addMonth(-1)">Prev </span>
<span>{{i | date:'MMM-yyyy'}}</span> // this value not being changed.
<span (click)="addMonth(1)">Next </span>
</div>
child.component.ts
export class ChildComponent implements OnInit {
@Input() i: Date;
@Output() monthChanged = new EventEmitter<Date>();
constructor() { }
ngOnInit(): void {
}
addMonth = (m: number) => {
this.i.setMonth(this.i.getMonth() m);
this.monthChanged.emit(this.i);
}
}
Что я пробовал?
this.changeDetectorRef.detectChanges();
ngOnChanges(changes: SimpleChanges) {
console.error(this.i); // no error log...
this.i = changes.i.currentValue;
console.error(this.i); // no error log...
}
Но ничего не работает. Что еще я должен использовать?
Ответ №1:
Я создал stackblitz, воспроизводящий вашу проблему. Вы можете проверить это здесь
Вы можете проверить журналы консоли. При обновлении внутри дочернего компонента с помощью this.i.setMonth(this.i.getMonth() m)
он также обновляет parent
s selectedMonth
. Потому что они являются одним и тем же объектом. Поскольку ссылка на объект не изменяется, Angular не будет запускать обнаружение изменений. Вы можете исправить это, создав новый объект внутри monthChanged
следующим образом
Изменить
monthChanged(d: Date) {
this.selectedMonth = d;
...
}
Для
monthChanged(d: Date) {
this.selectedMonth = new Date(d);
...
}
Ответ №2:
Данные будут обновлены, когда будет обновлена вся ссылка. Если вы просто обновите некоторые свойства внутри этого объекта, он не будет запущен. Вам нужно изменить ссылку на переданный объект.
Пример
<child [data]="myData"></child>
Если вы обновите myData.test= "YourData",
, это не сработает. Вам нужно что-то сделать
this.myData = changedData;
Обходным путем может быть использование перехвата жизненного цикла doCheck и попытка проверить изменение свойства вручную. Но, как правило, удобнее изменить ссылку.
Проверьте свое значение здесь
// on every change of @input 'name', this method will be triggered
ngOnChanges() {
this.data=changedData
}