Я использую @ ngrx/store для приложения Angular 2.Обновление объекта в ngrx/store
В моем магазине хранится список, скажем, Book
объектов. Я хочу обновить поле в одном из этих объектов. У меня также есть Наблюдаемый экземпляр книги, который я ищу для обновления (скажем, selectedBook
).
Чтобы сделать обновление, я намерен вызвать редуктор с помощью UpdateBookAction
и полезной нагрузки новой книги. Поэтому я делаю глубокую копию существующего объекта Book, подписываясь на selectedBook
, а затем вызывая Object.assign().
Но когда я пытаюсь записать в одно из полей копии, я получаю следующую ошибку. (Это случается та же ошибка, я получаю, если я стараюсь писать непосредственно на объект книги в магазине.)
Ошибка
Cannot assign to read only property 'name' of object '#<Object>' at ViewWrappedError.BaseError [as constructor]
Код
ngOnInit() {
this.book$ = this.store.let(fromRoot.getSelectedBook);
//...
}
someFunction() {
//...
this.book$.subscribe(book => {
let updatedBook = Object.assign({}, book);
updatedBook.name = 'something else'; // <--- THIS IS WHAT THROWS
let action = new BookUpdateAction(updatedBook);
this.store.dispatch(action);
}
}
Уточнение после Комментариев
Я был в предположении, что у меня может быть действие с полезной нагрузкой, которая была не всем состоянием магазина. (На самом деле это кажется необходимым, нет?) Я уверен, что это так, учитывая документацию.
Действие Я ищу взять что-то вроде этого:
Action = UPDATE, payload = {'id': 1234, 'name': 'something new'}
Как уже упоминалось, я намерен сделать на этот вызов, как это:
this.store.dispatch(action);
Предположительно под капотом, ngrx является передавая мое действие редуктору вместе с (неизменяемым) текущим состоянием.
Итак, оттуда все должно работать нормально. Моя логика внутри редуктора не мутирует существующее состояние, оно просто создает новый из существующего состояния и полезной нагрузки, в которой я прошел.
Настоящий вопрос заключается в том, как я могу разумно построить новый " objectToUpdate ", чтобы я мог передать это как полезную нагрузку.
я мог бы сделать что-то вроде этого:
this.book$.subscribe(book => {
let updatedBook = new Book();
updatedBook.id = book.id;
//set all other fields manually...
updatedBook.name = 'something else';
let action = new BookUpdateAction(updatedBook);
this.store.dispatch(action);
}
Но мы не просто говорим о двух полей здесь ... что, если моя книга имеет несколько полей? Должен ли я вручную создавать с нуля новую книгу каждый раз только для обновления одного поля?
Мое решение состояло в том, чтобы сделать глубокую копию, используя Object.assign({}, book)
(и не мутировать старый!), А затем внести обновление только в поле, которое я искал, чтобы коснуться.
Можете ли вы опубликовать определение объекта книги? Похоже, это может быть проблема с свойством write only. –
Да, видя определение книги, было бы полезно. У вас такая же проблема, когда вы делаете все это за один раз? например 'Object.assign ({}, book, {name: 'something else'})'? – rob3c