1

我订阅了一个 observable (getContentfulEntry) 来获取一些数据,但也从另一个 observable (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 不会更新视图中的数据。知道我做错了什么或如何解决这个问题吗?

4

2 回答 2

1

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

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

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() 的返回值分配给充当 Observable的BehaviorSubject (来自 rxjs)。您可以订阅 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);
    });
});
于 2018-09-27T19:00:54.820 回答
0

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

于 2018-09-27T18:41:03.403 回答