-
Angular 6.0.1
-
ngRx 6.0.1
我在视图中设置了插值:
{{firstName}}
当绑定的字段的值发生更改时,它不会更新 . 值 is 虽然正在改变 - 如果我将其记录到订阅内的控制台,我会看到更新的值 . 它只是不在UI中更新 .
这是相关的代码:
我的组件订阅:
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()
,则UI会更新 . 但在我看来,我通常不需要像这样使用 ChangeDetectorRef
,它应该"just work" .
我认为问题是我的深层嵌套属性( cp.primaryName.value.parsedValue.givenNames
) . 我从非ngRx项目中继承了这些实体,但我认为我的下一步是尝试展平该结构以查看是否使ngRx和Angular变化检测器更快乐 .
还有什么我想念的吗?
谢谢,
TTE
UPDATE
我只需更新订阅中组件上的本地属性,就可以将深层嵌套属性从图片中删除 . 所以 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
未更新 - 它显示我在声明时指定的值 . 但是,如果在声明属性时未指定值,则会在UI中正确显示订阅中指定的值 .
UI中正确显示了newProp
is
我现在完全感到困惑 . It seems like once a property has a value it is never updated in the UI ,即使值本身确实发生了变化(我可以通过在更新值后登录到控制台来判断) .
我没有明确地为组件设置 ChangeDetectionStrategy
,所以它是 Default
.
如果我打电话给 detectChanges
,一切都有效,但我不认为这是必要的 .
1 回答
当父组件的更改检测策略设置为
OnPush
时,此父级's tree of components will not be checked by angular'的更改检测机制,尽管每次@Input
属性更改时仍会调用此父级及其子级ngOnChanges
方法 . 要让angular知道此树中的某个组件需要更新,请将ChangeDetectorRef
注入该组件并使用其API通知有关更新的角度,例如detectChanges
或markForCheck