2017-07-24 110 views
-2

我試圖向我的服務添加一個幫助器方法,該方法將在返回Observable的同一服務中調用另一個方法。輔助方法需要返回一個布爾值。問題是確定返回值是true還是false是在顯然是異步的訂閱塊內完成的。所以即使通過這個值是真的我仍然總是得到一個虛假的回報。也許試圖混合同步和異步編程這不是一個好方法。函數在內部異步結果完成之前返回值

在我的部分我想作以下調用服務:

this.isAdmin = this.teamsService.isAdmin(this.teamId, this.user['userId']) 

服務:

getAssociations(id, postfix) { 
    return this.httpService.get(this.base, id, postfix) 
    .map((response) => { 
     return this.responseHandler.handleData(response); 
    }) 
    .catch((error) => { 
     return this.responseHandler.handleError(error); 
    } 
); 
} 

isAdmin(teamId, userId) { 
    let isAdmin = false; 

    this.getAssociations(teamId, '/teamMembers') 
    .subscribe(
     _data => { 
     if (_data['teamMembers']) { 
      for (let i = 0; i < _data['teamMembers'].length; i++) { 
      if (_data['teamMembers'][i]['id'] === userId) { 
       isAdmin = true; 
       break; 
      } 
      } 
     } 
     } 
    ); 

    return isAdmin; 
} 

所以isAdmin方法總是返回false原因很明顯。我最初是通過執行以下處理這個邏輯組件內部:

private checkIsAdmin() { 
    this.teamsService.getAssociations(this.teamId, '/teamMembers') 
    .subscribe(
     _data => { 
     if (_data['teamMembers'] && _data['teamMembers'].length) { 
      _data['teamMembers'].map(member => { 
      if (member['id'] === this.user['userId']) { 
       this.isAdmin = true; 
      } 
      }); 
     } 
     this.spinner.hide(); 
     this.loading = false; 
     }, 
     _error => { 
     this.spinner.hide(); 
     } 
    ); 
} 

這工作得很好,直到我不得不重複上的其他組件這個相同的邏輯。所以我試圖想出一種方法將該邏輯抽象爲服務本身返回一個布爾值,因爲這是我真正需要的函數。

我已經嘗試了一些想法,但他們都沒有工作。任何幫助都會很棒。謝謝。

回答

0

您也可以將所有控制進入Rx流的邏輯如下:

isAdmin(teamId, userId) { 
    return this.getAssociations(teamId, '/teamMembers') 
    .mergeMap(data => data['teamMembers'] != null ? Rx.Observable.empty() : Rx.Observable.from(data['teamMembers'])) 
    .filter(user => user['id'] === userId) 
    .mapTo(true) // found admin user 
    .take(1) 
    .concat(Rx.Observable.of(false));//default state; no admin user 
} 

取決於getAssociations()的使用,您也可以從Observable<ResponseTeamWrapperSomething>改變它的返回類型簽名向Observable<TeamMember>所以你可以失去mergeMap運營商在這個函數。

通過移動此邏輯並將您的自定義控制流程替換爲平臺提供的功能,可以減少代碼正在執行的認知過載。這也減少了您的測試負擔,因爲您不必測試框架提供的邏輯。

0

落下投票哪個爛,因爲沒人告訴過你爲什麼。如果你不要求他們說出原因,讓人們投票的能力似乎是不合邏輯的。你如何期待任何人學習這種方法。

反正我發佈解決方案。

我改變了呼叫的組件:

this.teamsService.isAdmin(this.teamId, this.user['userId']) 
    .subscribe(response => { 
    this.isAdmin = response; 
    } 
); 

並更新方法的服務裏面:

isAdmin(teamId, userId) { 
    return this.getAssociations(teamId, '/teamMembers') 
    .map(_data => { 
     let isAdmin = false; 
     if (_data['teamMembers']) { 
     for (let i = 0; i < _data['teamMembers'].length; i++) { 
      if (_data['teamMembers'][i]['id'] === userId) { 
      isAdmin = true; 
      break; 
      } 
     } 
     } 
     return isAdmin; 
    }); 
} 
相關問題