Angular 过滤两个可观测数据的正确方法

Angular 过滤两个可观测数据的正确方法,angular,rxjs,observable,Angular,Rxjs,Observable,我的任务是根据另外两个列表获取可观察列表。下面是有效的代码,但我想知道它是否正常(从性能角度来看): get availabledevaluelanguages$():可观察{ 返回此.languageCodesLookUpdatea$.pipe( withLatestFrom(this.languageData$), 映射([lookupLanguages,CodeValue])=>{ const codeValueLanguageCodes=codeValues.map(codeValue=

我的任务是根据另外两个列表获取可观察列表。下面是有效的代码,但我想知道它是否正常(从性能角度来看):

get availabledevaluelanguages$():可观察{
返回此.languageCodesLookUpdatea$.pipe(
withLatestFrom(this.languageData$),
映射([lookupLanguages,CodeValue])=>{
const codeValueLanguageCodes=codeValues.map(codeValue=>codeValue.language.id);
返回lookupLanguages.filter(lookupLanguage=>
!codeValueLanguageCodes.includes(lookupLanguage.id));
}),
catchError(错误=>{
归还([]);
})
)
}
languageData$包含网格的数据。它是一个复杂属性CodeValue的列表,每个属性都包含不同的语言languageCodesLookUpdatea$是所有可用语言的完整列表AvailableDevalueLanguages$需要包括dropdownlist的语言,需要能够在表单上每个代码值只添加一种语言


LanguageCodesLookUpdatea$加载到组件Init上(在处理页面时,它不太可能更改)。相应地,languageData$在我们向表单中的CodeValue列表添加一个新条目后会发生更改。

从性能角度来看,您的代码看起来不错,使用
和LatestFrom
是组合流的典型方法

然而

LanguageCodesLookUpdatea$加载在组件Init上(在处理页面时它不太可能更改)

使用
withLatestFrom
仅在源可观测发射时发射

languageData$在表单中的CodeValue列表中添加一个新条目后会发生更改

因此,我假设发生这种情况时,您希望
可用的贬值语言$
。 如果是这种情况,您应该使用
combinelatetest

availableCodeValueLanguages$ = combineLatest(
  this.languageCodesLookupData$,
  this.languageData$
).pipe(
  map(([lookupLanguages, codeValues]) => {
    const codeValueLanguageCodes = codeValues.map(codeValue => codeValue.language.id);
    return lookupLanguages.filter(lookupLanguage =>
      !codeValueLanguageCodes.includes(lookupLanguage.id));
  }),
  catchError(error => {
    return of([]);
  })
);
如果需要,可以将
codeValueLanguageCodes
定义为它自己的可观察对象

codeIds$ = this.languageData$.pipe(
    map(codeValue => codeValue.language.id)
);

availableCodeValueLanguages$ = combineLatest(
  this.languageCodesLookupData$,
  this.codeIds$
).pipe(
  map(([languages, codeIds]) => languages.filter(
    language => !codeIds.includes(language.id));
  ),
  catchError(error => {
    return of([]);
  })
);

看起来不错,您也可以使用
combileLatest
操作符来实现这一点。您不需要使用
get
,只需定义为
AvailableDevalueLanguages$=this.LanguageCodesLookUpdatea$.pipe(…)
@bizzybob-从性能角度看是更好还是更短?:)再短一点。。。没有性能优势:-(我有另一种不同的实现方式,使用我的自定义
导出类excludeDsFilterPipe实现PipeTransform
(其代码很简单,没有显示用于bravity)如下:
LicenseSlookUpdatea$| async | excludeDsFilter:{excludeId:NonAvailableModuleLicenceId,isNumeric:true}
excludeID
派生为
this.store.select(state=>state.modulelicenceaccess.pipe(takeUntil(this.destroy)).subscribe((state:ModuleLicences.state)
在组件构造函数中。您能告诉我它是否也可以吗?我认为这样做性能可以很好。我的首选是将逻辑放入控制器而不是管道。管道很好,因为它们可以以干净的方式执行逻辑,您可以在模板中轻松阅读。但是如果您需要将对象传递给管道,它变得凌乱,失去可读性。因此,我认为在控制器中的可观察流上执行转换逻辑更容易。
codeIds$ = this.languageData$.pipe(
    map(codeValue => codeValue.language.id)
);

availableCodeValueLanguages$ = combineLatest(
  this.languageCodesLookupData$,
  this.codeIds$
).pipe(
  map(([languages, codeIds]) => languages.filter(
    language => !codeIds.includes(language.id));
  ),
  catchError(error => {
    return of([]);
  })
);