Я показываю список задач в todo с ngFor и флажок для переключения состояния задачи. Я использую магазин от ngrx со следующим государственным интерфейсом:Как использовать changeDetectionStrategy.onPush для корректного обновления объекта?
export interface State {
tasks: Task[];
index: { [_id: string]: Task };
};
Это редуктор, который отвечает за обновление задачи, когда изменение статуса:
case TaskActions.UPDATE_TASK_SUCCESS: {
const task = action.payload;
state.index[task._id] = Object.assign(state.index[task._id], task);
return state;
}
И вот задача c omponent которые принимают задачу @Input и имеет changeDetectionStrategy установлен OnPush:
import { Component, OnInit, Input, ChangeDetectionStrategy, DoCheck } from '@angular/core';
import {Store} from '@ngrx/store';
import { AppState } from '../../../../domain';
import { TaskActions } from '../../../../domain/actions';
@Component({
selector: 'task',
templateUrl: './task.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
styleUrls: ['./_task.component.scss']
})
export class TaskComponent implements OnInit, DoCheck {
@Input() task;
constructor(
private store: Store<AppState>,
private TaskActions: TaskActions
) { }
ngOnInit() {
}
ngDoCheck() {
console.warn('Check');
}
public toggleTaskStatus(_task) {
var new_task = Object.assign({}, _task, {['status']: (_task.status == 'todo' ? 'done' : 'todo')});
this.store.dispatch(this.TaskActions.updateTask(new_task));
}
}
При такой конфигурации, в первый раз я нажимаю на флажке задание внутри магазина обновляется, но Пользовательский интерфейс не отражает никаких изменений. Во второй раз вместо этого пользовательский интерфейс начинает переключать свой статус, но не соответствует состоянию хранилища (когда состояние задачи «todo» в хранилище, пользовательский интерфейс «сделан»). Более того, чтобы обновиться, пользовательский интерфейс не ждет действия успеха в редукторе (услуга создает наблюдаемый с небольшим перерывом в 1 секунду).
Если для параметра changeDetectionStrategy установлено значение по умолчанию, все работает корректно, с обновлением пользовательского интерфейса в соответствии с состоянием хранилища.
Что я делаю неправильно? Рассматривается ли неизменность состояния или некоторые проблемы внутри компонента?