RxJs:由2个独立的可观测量引发的可观察性

时间:2017-10-18 15:08:36

标签: javascript angular rxjs reactive-programming rxjs5

我有一个名为&#34; workcentersFiltered&#34;类型Observable<Workcenter[]>

当我选择工厂时,我可以使用以下代码成功过滤我的工作中心 - 没问题:

this.workcentersFiltered = this.newLineForm.get('plant').valueChanges
      .flatMap(selectedPlant => {
        return this.dataStore.Workcenters.map(workcenters => {
          return workcenters.filter(x => x.PlantNumber === selectedPlant.PlantNumber);
        });
      });

问题是,当一个完全不同的,独立的可观察的&#34; 'workcenter'.valuechanges&#34;时,我想进一步缩小该数组。发出一个字符串(它是一个输入字段 - 我正在尝试实现自动完成)。

所以问题是,如何订阅this.newLineForm.get('workcenter').valueChanges,以便它发出的字符串值可用于进一步缩小数据范围&#34;隐藏&#34;在workcentersFiltered内(已与this.newLineForm.get('plant').valueChanges绑定。

我的困境是否有意义?我必须改为将workcenteresFiltered改为aBehaviorSubject,或者这里的解决方案是什么?

编辑更多解释

plant-forminput.valuechanges发出更改时,workcentersFiltered从dataStore.Workcenters获取数据,因为选择了工厂。因此,我可以将所有工作中心缩小到仅与所选工厂匹配的工作中心。它与我上面的代码一起工作正常。

但是,我想介绍一个关于plant-forminput.valuechanges和workcentersFiltered之间序列的新操作。基于workcenter-forminput.valuechanges的排放,我想进一步缩小选项范围。

因此,在我的用户界面上的第1步,用户可以从下拉列表中选择工厂,并过滤掉其他工厂的所有工作中心 - 这是有效的。

然后,步骤2是让用户选择特定的工作中心。这是一个文本输入字段。我想要在这里键入的每个字母(在workcenter-forminput.valuechanges上发出),以进一步缩小选项范围(自动完成)。

我很难想象解决方案,因为步骤2中新引入的observable(workcenter-forminput.valuechanges)仅在它发出时才相关。

1 个答案:

答案 0 :(得分:3)

您可以使用combineLatest

我无法按照您的完整描述进行操作,因此我只提供一个近似示例,您可以根据具体用例进行调整:

workcentersForPlant = this.newLineForm.get('plant').valueChanges
      .flatMap(selectedPlant => {
        return this.dataStore.Workcenters.map(workcenters => {
          return workcenters.filter(x => x.PlantNumber === selectedPlant.PlantNumber);
        });
      });

const workCenterNameChanges = this.newLineForm.get('workCenterName').valueChanges;

// combine the 2 observables, this will trigger when either observable
// changes.  Use the combined values to do the filtering by name
this.workcentersFiltered = Observable
  .combineLatest(workcentersForPlant, workCenterNameChanges$)
  .map(([workCenters, workCenterName]) => workCenters.filter(w => w.name.startsWith(workCenterName)));