Правильно ли я здесь работаю с Наблюдаемым?
Я вижу здесь 2 потенциальных проблемы:
- Вы устанавливаете
items$
Наблюдаемое в вашем обслуживать новый экземпляр каждый раз, когда вы обновляете соответствующий элемент в текущем массиве. - Вы устанавливаете значение этого Observable для того же экземпляра массива, поэтому Angular обнаружение изменений не делает ' Не думаю, что массив изменился (хотя значения в пределах он имеет).
Давайте обратимся к этим:
Вы можете использовать посредника Subject
для запуска значений, передаваемых на Observable
из вашего сервиса, и вызова .next
для него, когда вы хотите обновить значения.
Вы делаете это, выставляя Observable
как обычно, построен из Subject
. Это сделано для того, чтобы внешние факторы не могли непреднамеренно / злонамеренно вызвать .next
непосредственно по теме.
могло бы выглядеть примерно так:
export class DefaultLayoutService {
private _navItems: <ICustomNavData[]>;
private readonly _itemsSubject = new Subject<ICustomNavData[]>();
items$: Observable<ICustomNavData[]> = this.itemsSubject.asObservable();
setNavItemAttribute(itemKey: string, itemAttribute: string, text: string) {
// code to update corresponding item in navItems array
this._itemsSubject.next(this.navItems);
}
}
, поскольку Observable
получен из Subject
, он будет выдавать последнее значение, которое вы передали Субъекту в вашем методе обслуживания.
Помните, что вам нужно будет вызвать .next
с первым значением _itemsSubject
, когда вы Сначала инициализируйте компонент и массив, чтобы его можно было выдать на Observable
.
При просмотре в режиме одной страницы приложения, вызывая вызов setNavItemAttribute с различными параметрами, навигация элементы остаются прежними.
Поскольку ссылка на сам массив не изменилась, обнаружение изменений Angular не выполняет повторную визуализацию с новыми значениями внутри массив. Кажется, это общая проблема, с которой люди сталкиваются.
Один из способов, которые я делал раньше, - это использование оператора распространения ...
для создания «нового» массива, используя старый. Таким образом, ссылка отличается и запускает обнаружение изменений для повторного рендеринга с использованием новых значений.
Примерно так:
setNavItemAttribute(...) {
// code to update the corresponding item in the existing navItems array
const navItemsCopy = [...this.navItems];
// use the new array reference to trigger change detection
this._itemsSubject.next(navItemsCopy);
}
Есть еще много способов сделать это, поэтому посмотрите вокруг и посмотрите, что подходит вам лучше всего и подходит ли вам.