当可观察数据更新时,如何更新视图中的数据?

时间:2018-09-27 18:03:20

标签: javascript angular typescript rxjs angular-changedetection

我正在订阅一个可观察的(getContentfulEntry)以获取一些数据,而且还从另一个可观察的(stateService)传递数据

this.langSubscription = this.stateService.getLanguage()
      .subscribe(val => {
        this.lang = val;
      });
      
    this.subscription = this.contentfulService.getContentfulEntry(this.footerEntryId, {locale: this.lang.toLowerCase()})
      .subscribe(res => {
        console.log('Footer Entries:: ', res);
        // this.contentfulData = res;
        this.filteredFooter = this.contentfulService.getFilteredEntryByProv(res, this.prov);
        console.log('Filtered Footer:: ', this.filteredFooter);
      });

将其作为参数。因此,更新this.lang时将获取新数据。但是,除非我单击刷新,否则this.subscription不会更新视图中的数据。知道我在做什么错或如何解决吗?

2 个答案:

答案 0 :(得分:1)

在getLanguage()返回值之前,您正在引用从stateService.getLanguage()返回的数据值。

通过在对getLanguage()的订阅中调用getContentfulEntry()来确保this.lang具有值。这将确保在调用getContentfulEntry()

时this.lang具有值
this.langSubscription = this.stateService.getLanguage()
  .subscribe(val => {
    this.lang = val;
    this.subscription = this.contentfulService.getContentfulEntry(this.footerEntryId, { locale: this.lang.toLowerCase() })
      .subscribe(res => {
        console.log('Footer Entries:: ', res);
        // this.contentfulData = res;
        this.filteredFooter = this.contentfulService.getFilteredEntryByProv(res, this.prov);
        console.log('Filtered Footer:: ', this.filteredFooter);
      });
  });

您还可以考虑将getLanguage()的返回值分配给BehaviorSubject(来自rxjs),该值充当Observable。您可以订阅BehaviorSubject,每次分配新值时,该行为都会发出一个值。我提到行为主体是一种管理可能随时间变化的参数的方法,但在此用例中并未考虑此解决方案的最佳实践。

lang = new BehaviorSubject<string>('');

this.langSubscription = this.stateService.getLanguage()
  .subscribe(val => {
    // this.lang will emit the next assigned value "val"
    this.lang.next(val);
  });

// subscribe to emitted value from this.lang
this.lang.subscribe(val => {
  this.subscription = this.contentfulService.getContentfulEntry(this.footerEntryId, { locale: this.lang.getValue().toLowerCase() })
    .subscribe(res => {
      console.log('Footer Entries:: ', res);
      // this.contentfulData = res;
      this.filteredFooter = this.contentfulService.getFilteredEntryByProv(res, this.prov);
      console.log('Filtered Footer:: ', this.filteredFooter);
    });
});

答案 1 :(得分:0)

由于angular的api调用是异步的,因此对api getContentFulEntry()的调用发生在对getLanguage()的调用完成之前。您的fulentry调用使用相同的语言,因此即使api调用仍在进行,它不会在UI上更新,就像您在浏览器控制台中看到的那样,它已传递旧语言值。  因此,请先完成第二种方法。