2016-10-04 60 views
1

我需要填寫三個控制層次結構:公司,分支機構,員工。 出用戶的服務我得到當前登錄用戶, 然後通過用戶的域名我接受他的全部數據作爲員工, 那麼每個員工的branchId我獲得分支對象, 然後我要求所有的公司,並設置控制值,如圖 currrent員工,當前分行和當前分行的公司。避免嵌套的觀測值

我最終得到了訂閱者的嵌套樹。 我怎樣才能避免這一點,並重構它更直接?

this.userService.getCurrentlyLoggedInUser().subscribe(
    user => { 
     this.user = user; 
     this.getEmployee(this.user.domainName).subscribe(
      employees => { 
       if (employees.length === 0) { 
        this.isLoading = false; 
        return; 
       } 
       this.getBranch(employees[0].branchId).subscribe(
        branches => { 
         if (branches.length === 0) { 
          this.isLoading = false; 
          return; 
         } 
         this.odata.companies().subscribe(
          companies => { 
           this.setDefaultValues(companies, branches[0], employees[0]); 
           this.isLoading = false; 
          }, 
          error => this.isLoading = false 
         ); 
        }, 
        error => this.isLoading = false 
       ); 
      }, 
      error => this.isLoading = false 
     ); 
    }, 
    error => this.isLoading = false 
); 

回答

0

爲了避免嵌套使用訂閱電話隨時可以映射從元分支回,如已經從主分支通過一些AJAX調用或一些其他的異步操作叉流,到主幹分支mergeMap

有關詳細信息,請參閱以下代碼。注意,只有一個預訂呼叫到中繼流。所有其他流都是mergeMap'回到中繼流中,因此不需要額外的訂閱。考慮訂閱一個流作爲脫離RxJS上下文並返回到正常的JS。這隻適用於副作用,如console.log命令。

const initialUserObj = { userId: 0, username: 'admin' }; 

const getUserGroup = function(id) { 
    console.log(`Requesting user group for user with id ${id}`); // debug only 

    const typeAdmin = { group: 'Administrator', rights: 'all' }; 
    const typeUser = { group: 'User', rights: 'restricted' }; 
    const timeout = Math.floor(Math.random() * 5000); 

    return new Promise((resolve, reject) => { 
    // Simulated API call with timeout 
    setTimeout(() => { 
     resolve(id === 0 ? typeAdmin : typeUser); 
    }, timeout); 
    }); 
} 

const getUserDetails = function(id) { 
    console.log(`Requesting user details for user with id ${id}`); // debug only 

    const timeout = Math.floor(Math.random() * 5000); 

    return new Promise((resolve, reject) => { 
    // Simulated API call with timeout 
    setTimeout(() => { 
     resolve({ fullName: id === 0 ? 'Administator himself' : 'Some User' }); 
    }, timeout); 
    }); 
} 

Rx.Observable.of(initialUserObj) 
    .flatMap(user => { 
    return Rx.Observable.fromPromise(getUserGroup(user.userId)) 
     .map(group => Object.assign({}, user, group)); 
    }) 
    .flatMap(user => { 
    return Rx.Observable.fromPromise(getUserDetails(user.userId)) 
     .map(details => Object.assign({}, user, details)); 
    }) 
    .subscribe(x => console.log(x)); 

Working sample on jsbin

+0

不同的是,對於後面的每個呼叫,我需要使用信息從以前的一個。也就是說,首先我得到用戶,然後我通過user.organizationId請求組織。在你的例子中,你總是和userId一樣。 – avj

+0

@avj你說得對,我在這兩種情況下都使用'user.userId',但你也可以在隨後的所有調用中使用所有其他值。有關擴展示例,請參閱https://jsbin.com/bakajuh/edit?js,console。 – dotcs

+0

是的,flatMap最後工作。 http://stackoverflow.com/questions/34104638/how-to-chain-http-calls-in-angular2有一個簡單的例子,我使用過。 – avj