首页 文章

角度内插值不会在订阅时更新

提问于
浏览
1
  • 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 回答

  • 3

    当父组件的更改检测策略设置为 OnPush 时,此父级's tree of components will not be checked by angular'的更改检测机制,尽管每次 @Input 属性更改时仍会调用此父级及其子级 ngOnChanges 方法 . 要让angular知道此树中的某个组件需要更新,请将 ChangeDetectorRef 注入该组件并使用其API通知有关更新的角度,例如 detectChangesmarkForCheck

相关问题