- Угловой 6.0.1
- нгРкс 6.0.1
У меня есть интерполированное значение, установленное в моем представлении:
{{firstName}}
Он не обновляется при изменении значения поля, к которому он привязан. Однако значение изменяется — если я выйду из консоли внутри подписки, я увижу обновленное значение. Он просто не обновляется в пользовательском интерфейсе.
Вот соответствующий код:
Подписка от моего компонента:
private subscribeToCurrentPerson(): void {
this.tState$ = this.store
.pipe(select(selectors.getCurrentPerson), takeWhile(() => this.componentActive))
.subscribe((cp: Person) => {
if (cp) {
const name: string = cp.primaryName.value.parsedValue.givenNames[0];
this.firstName = name;
console.log('name: ' + name); // <-- this shows correct new value
}
});
}
subscribeToCurrentPerson
вызывается из компонента ngOnInit. До этого свойство firstName
не было определено.
Селектор selectors.getCurrentPerson
выглядит так:
export const getCurrentPerson: MemoizedSelector<{}, Person> =
createSelector(getTState, (tState: ITState) => {
console.log('selector: ', tState); // <-- this logs the correct new value
return tState ? tState.currentPerson : null;
});
Значение currentPerson
, возвращаемое селектором, является вновь созданным объектом. Это происходит при первом запуске приложения, поэтому до этого tState
не определено.
Если я введу ChangeDetectorRef
в свой конструктор и вызову cdr.detectChanges()
внутри подписки, пользовательский интерфейс обновится. Но мне кажется, что обычно мне не нужно использовать ChangeDetectorRef
таким образом, что он должен «просто работать».
Я думаю, проблема в моем глубоко вложенном свойстве (cp.primaryName.value.parsedValue.givenNames
). Я унаследовал эти объекты от проекта, отличного от ngRx, но я думаю, что мой следующий шаг — попытаться сгладить эту структуру, чтобы посмотреть, сделает ли это ngRx и детектор изменений Angular более счастливыми.
Есть ли что-то еще, что мне не хватает?
Спасибо,
ТТЭ
ОБНОВЛЕНИЕ
Я убрал глубоко вложенное свойство из картины, просто обновив локальное свойство моего компонента внутри подписки. Итак, функция subscribeToCurrentPerson
теперь выглядит так:
private subscribeToCurrentPerson(): void {
this.tState$ = this.store
.pipe(select(selectors.getCurrentPerson), takeWhile(() => this.componentActive))
.subscribe((cp: Person) => {
this.myProp = 'goodbye';
this['newProp'] = 'world';
});
}
myProp
— это существующее свойство моего компонента, которое я добавил для тестирования. newProp
не существует до тех пор, пока он не будет добавлен с помощью скобок внутри подписки. Вот результаты:
myProp
не обновляется — показывает значение, которое я присвоил ему при объявлении. Однако, если я не назначу значение при объявлении свойства, то значение, назначенное в подписке, правильно отображается в пользовательском интерфейсе.newProp
отображается в пользовательском интерфейсе правильно
Я теперь совершенно сбит с толку. Похоже, что если у свойства есть значение, оно никогда не обновляется в пользовательском интерфейсе, даже если само значение изменяется (о чем я могу узнать, выполнив вход в консоль после обновления значения).
Я не устанавливаю явно ChangeDetectionStrategy
для компонента, так что это Default
.
Все работает, если я позвоню detectChanges
, но я не думаю, что это необходимо.
OnPush
обнаружения изменений. - person Meme Composer   schedule 05.08.2018