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([]);
})
);