首页 > 解决方案 > 如何从 Observable 中过滤数组以获得浅拷贝而不是深拷贝?

问题描述

code我的组件使用通过 xhr 加载到 Observable 的一些数据(具有可被视为 id的属性的“ksr”项数组)

dictionaries = {
  ksr$: this.dictionaryService.fetchDictionaryByName('KSR'),
  ...
}

它的一部分被过滤到另一个 Observable 中,如下所示:

formSuggestions = {
  ksrCodes$: this.dictionaries.ksr$.pipe(map((plainKsrArray: Array<any>) =>
    plainKsrArray.filter(ksrItem => ksrItem.levelName == "position"
  )),
  ...
}

我预计一旦加载数据,中的项目就是中的项目.formSuggestions的浅表副本.dictionaries,但情况似乎并非如此。具体如下测试函数

async debugDictionariesAndSuggestions() {
  let dictionary = await this.dictionaries.ksr$.toPromise();
  let dItem = dictionary.find(item => item.code == '01.11.11.01.1.01.01-0001');
  let suggestions = await this.formSuggestions.ksrCodes$.toPromise();
  let sItem = suggestions.find(item => item.code == '01.11.11.01.1.01.01-0001');
  console.log('found by code:', dItem, sItem, dItem == sItem ? 'same' : 'not same');
  console.log(JSON.stringify(dItem) == JSON.stringify(sItem) ? 'they look the same' : 'they look different');
}

找到 and 中的项目dictionarysuggestions但报告它们不是同一件事(尽管dItemand的所有嵌套属性sItem都相同,但报告“它们看起来相同”)。为什么会这样,我如何修改从可观察对象中处理此类数据(我如何过滤dictionaries.ksr$formSuggestions.ksrCodes$),以便后者由前者中的项目(浅拷贝)组成?

标签: angularrxjsangular2-observables

解决方案


就像@JBNizet 指出的那样,shareReplay运营商是解决这个问题的一种非常简单的方法。从 http 服务 observable 派生的 observable 的正常行为是 - 每个订阅(在我的情况下是承诺的:await this.dictionaries.ksr$.toPromise()await this.formSuggestions.ksrCodes$.toPromise())都会触发一个新请求。但如果我这样修改它:

dictionaries = {
  ksr$: this.dictionaryService.fetchDictionaryByName('KSR').pipe(shareReplay()),
  ...
}

dictionaries.ksr$观察的和派生的仅触发一个请求,并且共享结果值,这正是我所寻找的。


推荐阅读