2016-10-04 14 views
1

3つのコントロールを企業、支店、従業員という階層構造で入力する必要があります。 私は現在ユーザーにログインしています ユーザーのドメイン名で私は従業員として の全データを受け取り、次に従業員のブランチIDを取得しました 私はすべての企業を要求し、制御値を 現住所の従業員、現在のブランチ、および現在のブランチの会社。ネストされたオブザーバブを避ける

私は加入者のネストされたツリーで終わる。 これを避け、より簡単にリファクタリングするにはどうすればよいですか?こうした使用してトランク枝に、いくつかのAJAXコールまたは他のいくつかの非同期操作を介してメインブランチからフォークされたストリームとして、いつでも戻ってメタブランチからマッピングすることができ、ネストされたサブスクライブのコールを、避けるために

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

mergeMap

詳細については、次のコードを参照してください。トランクストリームへのサブスクライブコールは1つだけです。他のすべてのストリームは、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

違いは、後続の各コールのために、私は、以前の1からの情報を使用する必要があるということです。すなわち、まずuserを取得し、次に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

関連する問題