按顺序链接可观察量

时间:2017-12-27 08:18:22

标签: angular typescript rxjs reactive-programming

在Angular中我想在路由resolve字段中返回一个包含列表的对象,对于列表中的每个项目,我想执行一个可以修改它的附加请求。它看起来像这样:

this.employeesService.getEmployees(route.parent.params['department'])
  .map(employeesResponse => {
    employeesResponse.employees.map(employee => 
      employee.status = this.employeesService.checkStatus(route.parent.params['department'], employee))
  })

getEmployees返回一个包装器响应对象:

{
  operationId: 1
  employees: [],
}

checkStatus返回一个字符串,该字符串是员工状态。

我知道这不起作用,但我尝试以多种方式做到这一点,并且不知道如何实现。我知道如何从第一个请求返回一个列表但是我必须保留这个包装器对象。

使用Rx执行此操作的最佳方法是什么?我对反应式编程概念很陌生。

3 个答案:

答案 0 :(得分:0)

您可以将.mergeMap()与并发参数一起使用,以便同时修改多个项目。这不是保留订单所以可能是一个问题。

如果需要订购,您可以使用.concatMap()

答案 1 :(得分:0)

我可以使用以下代码轻松实现返回列表(已修改的列表)的结果:

this.employeesService.getEmployees(route.parent.params['department'])
  .mergeMap((employeesResponse: EmployeesResponse) => employeesResponse.employees)
  .mergeMap((employee: Employee) => this.checkEmployee(route.parent.params['department'], employee)
  .map(statusResponse => {
    employee.status = statusResponse.status;
    return employee
  })

);

但是,我不想要那个清单。我希望它包含在EmployeeResponse中。这是我遇到问题的地方,而不是使用哪个操作员。

答案 2 :(得分:0)

根据您的回答,但是在mergeMap中进行状态检查映射并使用toArray重建列表。

唯一丢失的是operationId。那有关系吗?

// Mock services
const routeParamsDept = 'Sales';
const employeesService = {
  getEmployees: (department) => {
    return Rx.Observable.of({
      operationId: 1,
      employees: [
        {name: 'Joe', status: 'Perm', dept: 'Sales'},
        {name: 'Jane', status: 'Temp', dept: 'Sales'}
      ]
    });
  } 
}
const checkEmployee = (department, employee) => Rx.Observable.of({status: 'Perm'})

const fetchedAndChecked = employeesService.getEmployees(routeParamsDept)
  .mergeMap(employeesResponse => employeesResponse.employees)
  .mergeMap(employee => {
    return checkEmployee(routeParamsDept, employee)
      .map(statusResponse => {
        employee.status = statusResponse.status;
        return employee
      })
  })
  .toArray()

fetchedAndChecked.subscribe(console.log)
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.6/Rx.js"></script>