简体   繁体   English

异步模型更新的Angular2 Update View

[英]Angular2 Update View on async model update

I've got a Angular2 component with dependency on a datastore. 我有一个依赖于数据存储的Angular2组件。 Template has some databinding on that store, eg "{{datastore.weather.curTemp}}" Datastore get's updated from time to time via http. 模板在该存储上具有一些数据绑定,例如“ {{datastore.weather.curTemp}}”。数据存储会通过http进行不时更新。

Now i understand that this works in an asnyc way - which is the cause my curTemp get's not updated automatically when new data arrives, right? 现在,我知道这可以以一种非常规的方式工作-这就是当新数据到达时,我的curTemp不会自动更新的原因,对吗?

My current solution would be to use an EventEmitter to notify my component on changes, but then I would need either a local variable to bind to, which could get messy, if I need a lot of variables from my datastore, or I would call detectChanges() on ChangeDetectorRef. 我当前的解决方案是使用EventEmitter通知组件有关更改,但是如果我需要从数据存储中获取大量变量,则需要绑定到本地变量,否则可能会造成混乱,或者我将调用detectChanges ()在ChangeDetectorRef。

Am I on the right track? 我在正确的轨道上吗? Or am I missing a simple way of populating my asny-data? 还是我缺少一种简单的填充asny数据的方法?

Thank you! 谢谢!

A way to solve your problem would be to make weather a Subject : 解决您的问题的一种方法是使weather成为Subject

datastore.service.ts datastore.service.ts

public weather: Subject<any> = new Subject(); // better make this private and expose it `asObservable` via a getter nethod

updateWeather(){
  http.get(...).subscribe(res => this.weather.next(res.json()))
}

You could then get a reference to that in your component.ts: 然后,您可以在component.ts中获得对此的引用:

public weather$: Observable<any>;
constructor (dataStore: DataStore){
  this.weather$ = dataStore.weather;
}

And use it in your template like this: 并像这样在您的模板中使用它:

{{(weather$ | async).curTemp}}

That way you also don't need to handle subscriptions when your component is destroyed as the async pipe does it for you. 这样,当组件被销毁时,您也不需要处理订阅,因为异步管道会为您执行订阅。

If your component is not updating, perhaps your async thread is running outside the NgZone, and you might need to update your component by making the assignment inside the component's NgZone . 如果您的组件未更新,则您的异步线程可能正在NgZone外部运行,并且您可能需要通过在组件的NgZone中进行分配来更新您的组件。

import {Component, NgZone} from "@angular/core";

@Component({
  selector: 'app',
  templateUrl: './app.component.html'
})

export class MyComponent {
  myValue: string;

  constructor(private ngZone: NgZone) {
  }

  getData() {
    const self = this;
    myAsyncCall().then(result => {
      ngZone.run(() => {
        self.myValue = result;
      });
    });
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM