Javascript 可以将其重构为示例中所示的更具可组合性的样式吗?
我是rxjs的新手,我提出的这个例子感觉不那么优雅。从本质上讲,我如何将3个截然不同的观测值组合成一个?你真的能像许多在线展示的例子那样,用高阶函数的方式来做吗Javascript 可以将其重构为示例中所示的更具可组合性的样式吗?,javascript,typescript,rxjs,Javascript,Typescript,Rxjs,我是rxjs的新手,我提出的这个例子感觉不那么优雅。从本质上讲,我如何将3个截然不同的观测值组合成一个?你真的能像许多在线展示的例子那样,用高阶函数的方式来做吗 createFilteredDataObservable(initialData: Observable<Data[]>, valueSource: Observable<any>, clickS
createFilteredDataObservable(initialData: Observable<Data[]>,
valueSource: Observable<any>,
clickSource: Subject<boolean>): Observable<Data[]> {
let data: Data[] = [];
let text = '';
initialData.subscribe(value => {
data= value;
});
function format(x: string): string {
return x.toLowerCase().trim();
}
function filter() {
if (text === '') {
return data;
}
const result = data.filter(d=> {
const name = format(d.DisplayName);
return name === text || name.includes(text);
});
return result;
}
return new Observable<Data[]>((observer) => {
clickSource.subscribe(_ => {
const result = filter();
observer.next(result);
});
valueSource.subscribe((v: string|Data) => {
if (typeof v !== 'string') {
return;
}
text = format(v);
const result = filter();
observer.next(result);
});
});
}
createFilteredDataObservable(初始数据:可观察,
价值来源:可观察,
点击来源:主题):可观察{
let data:data[]=[];
让text='';
initialData.subscribe(值=>{
数据=价值;
});
函数格式(x:string):string{
返回x.toLowerCase().trim();
}
函数过滤器(){
如果(文本==''){
返回数据;
}
const result=data.filter(d=>{
const name=格式(d.DisplayName);
返回名称===text | | name.includes(text);
});
返回结果;
}
返回新的可观察对象((观察者)=>{
单击源。订阅(\u=>{
const result=filter();
下一步(结果);
});
valueSource.subscribe((v:string | Data)=>{
如果(v的类型!=='string'){
返回;
}
文本=格式(v);
const result=filter();
下一步(结果);
});
});
}
完全取决于您想做什么,但大致上应该是
const filtered = data.pipe(switchMap(data => {
return value.pipe(startWith(''), combineLatest(clicks.pipe(startWith(null))), map(([value, _]) => {
return data.filter(item => item.includes(value));
}));
}));
以下是您可以使用的要点:
为了简洁起见,我省略了格式
和简化的过滤器
,但这可以通过在起始值
和组合测试
之间的映射
来实现。这将在一些次要方面表现出与代码不同的行为,您可以根据需要进行调整
在您的示例中,如果initialData
是冷的,需要一段时间才能触发,并且单击源代码和valueSource
更早地触发,那么您可以得到一个空数组。在我的示例中,在initialData
至少触发一次之前,您不会得到任何结果。如果需要此行为,可以在开关映射
之前使用data
上的startWith
此外,在您的示例中,如果第二次触发initialData
,则不会发生任何事情(可观察对象将继续过滤旧的原始值),在本例中,如果再次触发initialData
,则它将切换到过滤新数组,但可能会丢失valueSource
中的值
在您的示例中,如果单击source
或valueSource
触发,您将无法获得任何开始时的结果,然后第一个结果将出现。我想不出一个方法来复制这个完全从我的头顶。一旦数据
触发,我的代码将立即触发一次。如果您在单击时关闭启动,则只有在单击源时才会启动。如果将startWith
置于value
打开状态,则只有当valueSource
至少触发一次时,才会触发。如果你真的需要这种行为,你可能会开始,而不是数据.filter
与合并(点击,值).pipe(开关映射(=>data.filter…
),它只需稍加修改,效果非常好。谢谢。