Angular interpolated value not updating on subscription

烈酒焚心 提交于 2019-12-11 08:08:05

问题


  • Angular 6.0.1
  • ngRx 6.0.1

I have an interpolated value set up in my View:

{{firstName}}

It is not updating when the value of the field it is bound to changes. The value is changing though - if I log it out to the console inside the subscription, I see the updated value. It just doesn't update in the UI.

Here's the relevant code:

Subscription from my component:

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 is called from the component's ngOnInit. Prior to this, the firstName property is undefined.

The selectors.getCurrentPerson selector looks like this:

export const getCurrentPerson: MemoizedSelector<{}, Person> = 
    createSelector(getTState, (tState: ITState) => {
      console.log('selector: ', tState); // <-- this logs the correct new value
      return tState ? tState.currentPerson : null;
    });  

The currentPerson value returned from the selector is a newly created object. This is happening on the first run of the application, so prior to this tState is undefined.

If I inject ChangeDetectorRef in my constructor and call cdr.detectChanges() inside the subscription, the UI updates. But it seems to me I don't typically need to use ChangeDetectorRef like this, that it should "just work".

I think the problem is my deeply nested property (cp.primaryName.value.parsedValue.givenNames). I inherited these entities from a non-ngRx project, but I think my next step is to try flattening that structure to see if that makes ngRx and the Angular change detector happier.

Is there something else I'm missing?

Thanks,

TTE

UPDATE

I've take the deeply nested property out of the picture by simply updating a local property on my component inside the subscription. So the subscribeToCurrentPerson function now looks like this:

private subscribeToCurrentPerson(): void {
        this.tState$ = this.store
          .pipe(select(selectors.getCurrentPerson), takeWhile(() => this.componentActive))
          .subscribe((cp: Person) => {
            this.myProp = 'goodbye';
            this['newProp'] = 'world';
      });
    }

myProp is an existing property on my component I added for testing. newProp does not exist until it is added via the bracket notation inside the subscription. Here's the results:

  • myProp is not updated - it shows the value I assigned it when it was declared. However, if I do not assign a value when the property is declared, then the value assigned in the subscription is shown in the UI properly.
  • newProp is shown in the UI correctly

I am now completely baffled. It seems like once a property has a value it is never updated in the UI, even if the value itself does change (which I can tell by logging to the console after updating the value).

I'm not explicitly setting the ChangeDetectionStrategy for the component, so it is Default.

Everything works if I call detectChanges, but I don't think that should be necessary.


回答1:


When a parent component has its change detection strategy set to OnPush then this parent's tree of components will not be checked by angular's change detection mechanism, although this parent and its children's ngOnChanges method is still being called every time any @Input properties change. To let angular know that some component in this tree needs to update, inject a ChangeDetectorRef into that component and use its API to notify angular about the update, e.g detectChanges or markForCheck




回答2:


A lot of times data updates from component will not reflect the HTML template. In such a case, you can use interpolation with ternary operators.

 {{firstName ? firstName : ''}}

It works for me. Hope this will work



来源:https://stackoverflow.com/questions/51690866/angular-interpolated-value-not-updating-on-subscription

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!