【问题标题】:How to filter RxJS observables of a redux store?如何过滤 redux 商店的 RxJS observables?
【发布时间】:2018-04-05 01:20:17
【问题描述】:

我正在使用 RxJS 来观察我的 redux 存储何时发生变化,如下所示:https://medium.com/@fahad19/streaming-redux-state-as-an-observable-with-rxjs-390a8f7bc08c

我有一个看起来像这样的对象:

 {
  commands: [
    {key: 'arrows', isEnabled: true, activeState: 1, numStates: 2 },
    {key: 'focus', isEnabled: false, hotKey: 'f' },
    {key: 'geometry', isEnabled: true, activeState: 1, numStates: 2 },
    {key: 'goToEnd', isEnabled: true },

这个“命令”数组中的每一项都成为 GUI 中的工具栏按钮。我已经编写了更改每个命令的各个属性的代码,但现在我需要监听每个命令的更改。

如何获取此流并通过commandkey 对其进行过滤,以便仅在焦点命令更改其isEnabled 和/或activeState 属性更改时触发?

【问题讨论】:

    标签: javascript filter rxjs observable


    【解决方案1】:

    您可以使用 distinctUntilChanged 运算符仅在值更改时收到通知

    store.map(state => 
       state.commands.filter(cmd => cmd.key === 'focus')[0].isEnabled)
      .distinctUntilChanged()
    

    【讨论】:

    • 我在这里试过:jsbin.com/qezogasuwe/1/edit?js,console 但是 distinctUntilChanged() 似乎不起作用。请注意,在链接的示例中,我两次得到相同的结果。
    • 啊,我知道我需要将一个函数传递给 distinctUntilChanged 进行比较。返回对象的默认比较不正确。
    • 是的,默认比较只是'==='。很高兴它现在可以工作了。
    【解决方案2】:

    您可以根据您的情况filter observables。当然,您需要利用 Array.prototype 中的 .map().filter() 函数:

    store$.filter(store => {
        return store
            .commands
            .filter(command => command.key == 'focus' && command.isEnabled)
            .length; //if length is greater than 0, means condition is met.
    })
    

    【讨论】:

    【解决方案3】:

    好的,我想出了一种方法来做我想做的事。请参阅下面的代码。有没有更好的办法?

    const store = Rx.Observable.create(function(observer) {
      let state = { commands: [
        {key: 'arrows', isEnabled: true, activeState: 0, numStates: 2 },
        {key: 'focus', isEnabled: false, hotKey: 'f' },
        {key: 'geometry', isEnabled: true, activeState: 1, numStates: 2 },
        {key: 'goToEnd', isEnabled: true }]
      };
    
      observer.next(state);
    
      state = { commands: [
        {key: 'arrows', isEnabled: true, activeState: 1, numStates: 2 },
        {key: 'focus', isEnabled: true, hotKey: 'f' },
        {key: 'geometry', isEnabled: true, activeState: 1, numStates: 2 },
        {key: 'goToEnd', isEnabled: true }]
      };
    
      observer.next(state);
    
      state = { commands: [
        {key: 'arrows', isEnabled: true, activeState: 1, numStates: 2 },
        {key: 'focus', isEnabled: true, hotKey: 'f' },
        {key: 'geometry', isEnabled: true, activeState: 1, numStates: 2 },
        {key: 'goToEnd', isEnabled: true }]
      };
    
      observer.next(state);
    });
    
    
    const subscribe = store.map( state => {
        const commands = state.commands.filter( cmd => cmd.key === 'arrows' );
        if( commands.length == 0 ) {
           return undefined; 
        }
        const result = {
           isEnabled: commands[0].isEnabled,
           activeState: commands[0].activeState,
        };
        return result;
    })
    .distinctUntilChanged( ( a, b ) => a.isEnabled === b.isEnabled && a.activeState === b.activeState )
    .subscribe(val => console.log(val));
    

    此处的工作示例:http://jsbin.com/xipaqusivi/1/edit?js,console

    基本上我只在 isEnabled 或 activeState 属性更改为指定的选定命令键(本示例中的箭头)时收到通知

    【讨论】:

      猜你喜欢
      • 2012-06-25
      • 2019-03-03
      • 1970-01-01
      • 1970-01-01
      • 2017-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-18
      相关资源
      最近更新 更多