Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 可以将其重构为示例中所示的更具可组合性的样式吗?_Javascript_Typescript_Rxjs - Fatal编程技术网

Javascript 可以将其重构为示例中所示的更具可组合性的样式吗?

Javascript 可以将其重构为示例中所示的更具可组合性的样式吗?,javascript,typescript,rxjs,Javascript,Typescript,Rxjs,我是rxjs的新手,我提出的这个例子感觉不那么优雅。从本质上讲,我如何将3个截然不同的观测值组合成一个?你真的能像许多在线展示的例子那样,用高阶函数的方式来做吗 createFilteredDataObservable(initialData: Observable<Data[]>, valueSource: Observable<any>, clickS

我是rxjs的新手,我提出的这个例子感觉不那么优雅。从本质上讲,我如何将3个截然不同的观测值组合成一个?你真的能像许多在线展示的例子那样,用高阶函数的方式来做吗

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…

),它只需稍加修改,效果非常好。谢谢。