2017-07-06 127 views
1

我有一個問題對象,其中一個屬性是一個工具對象的數組。問題和工具是我數據庫中的兩個不同的表格。如何使用先前的http請求中的數據創建http請求?

在我的問題-log.component我調度一個動作來搜索匹配我的搜索查詢的問題。這工作得很好。

我一直在試圖做的下一件事是,將問題列表和每個問題ID都傳遞給我的工具服務,以便我可以獲得與該問題相關的工具。

我能夠得到這個工作的方式是添加另一個偵聽ISSUE.SEARCH.COMPLETE操作的效果。然後,我瀏覽了我的工具服務中的一系列問題,以便我可以爲每個問題ID調用API服務,並將工具屬性添加到該問題。這在一些方面似乎是錯誤的。一個是,對於大型問題列表,需要很長時間才能加載所有工具,如果我嘗試啓動另一個問題搜索,我必須等待工具從前一個加載,然後我的應用纔會響應。二,將整個問題數組傳遞到工具服務似乎是錯誤的,因爲我一次只需要一個問題id來獲取與該問題相關的工具列表;這不會使我的工具服務在我的應用程序的其他地方輕鬆重新使用。

我希望不要等到我的API調用才能獲取問題列表,然後才能開始獲取與每個問題ID相關的工具。是否可以在我的issuesSearch $ effect中添加代碼,在下面評論的地方,開始添加工具,因爲我的問題列表正在構建中?

組件:

@Component({ 
selector: issue-log, 
template: ` 
    <issue-search (search)="search($event)></issue-search> 
    <issue-list [issues]=$issues | async></issue-list> 
`, 
changeDetection: ChangeDetectionStrategy.OnPush 
}) 
export class IssueLogComponent { 
    issues$: Observable<Issue[]>; 

    constructor(private store: Store<fromRoot.State>) { 
    this.issues$ = store.select(fromRoot.getIssueSearchResults); 
    } 

    search(query) { 
    this.store.dispatch(new issue.IssueSearch(query)); 
    } 
} 

效果:

@Effect() issueSearch$: Observable<Action> = this.actions$ 
    .ofType(issue.ISSUE_SEARCH) 
    .debounceTime(300) 
    .map(toPayload) 
    .switchMap(query => { 
    if (query === '') { 
     return empty(); 
    } 
    const nextSearch$ = this.actions$.ofType(issue.ISSUE_SEARCH).skip(1); 
    return this.issueService.getIssuesFromQuery(query) //calls API service 
     .takeUntil(nextSearch$) 
     .mergeMap((res: Issue[]) => { 
     // How do I make another API call here, passing data from each element of res array? 
     return Observable.from([ 
      new issue.IssueSearchComplete(res) 
     ]) 
     }) 
     .catch(() => of(new issue.IssueSearchComplete([]))); 
}); 

我也試圖從我的問題服務中打電話給我服務的工具,但不認爲這是正確的做法無論是。

+0

我認爲這[post](https://stackoverflow.com/questions/35268482/chaining-rxjs-observables-from-http-data-in-angular2-with-typescript?rq=1)是有幫助的方向使用.flatMap或可能.forkJoin,但我仍然不確定將其包裝在循環中以獲取我的響應的每個元素。也許使用.forEach? – ksimonson10

+0

因此,您想要獲得問題並能夠立即訪問這些問題,同時在每個問題中使用數據在後臺進行更多異步調用? – Lansana

+0

是的,這可能嗎? – ksimonson10

回答

1

由於在使用這些問題的數據發出其他異步請求之前需要立即訪問問題的結果,因此您可能需要使用某種RxJS Subject

您可以觀察該主題的問題,並訂閱所有最終調用結果的可觀察值。

概念細分:

  1. 我們獲取的問題
  2. 我們通過問題,另一個可觀測流,使他們能夠立即訪問
  3. 我們使用的問題,使其他的異步調用
  4. 回到最終通話的結果,也可以訂閱

所以你必須訂閱用這種方法對兩個可觀察的流進行分析。

下面是一個簡單的,人爲的例子:

@Injectable() 
export class FooService { 
    issuesSubject: BehaviorSubject<Issue[]> = new BehaviorSubject([]); 

    get issues$(): Observable<Issue[]> { 
     return this.issuesSubject.asObservable(); 
    } 

    getIssuesAndMakeOtherAsyncCalls(): Observable<any> { 
     return this.issueService 
        .getIssuesFromQuery(query) 
        .flatMap((issues: Issue[]) => { 
         // This is where you add issues to the issues stream 
         this.issuesSubject.next(issues); 

         // This is where you make other HTTP calls using the issues 
         return this.makeSomeOtherCallsUsingIssues(issues); 
        }) 
    } 
} 

在您的組件:

@Component({}) 
export class FooComponent implements OnInit { 
    ngOnInit() { 
     this.issueService.getIssuesAndMakeOtherAsyncCalls().subscribe(res => { 
      // `res` will be the result of the `makeSomeOtherCallsUsingIssues(issues)` call in the service 
     }); 

     this.issueService.issues$.subscribe((issues: Issue[]) => { 
      // You will get issues here when the `this.issuesSubject.next(issues)` line is called in your service 
     }); 
    } 
} 

這是否對你的工作?

+0

謝謝你的回答!我正在嘗試關注,但是您的方法名稱中是否存在一些拼寫錯誤?我有點麻煩。在組件中,this.issueService.getAllIssues()應該是'getIssuesAndMakeOtherAsyncCalls()'? – ksimonson10

+0

對不起,對,應該是!固定。 – Lansana

+0

再次感謝您的回答,但它沒有解決對我來說最大的問題,那就是我實際上需要訪問問題數組的每個元素中的屬性,並將其傳遞到其他異步調用中。我認爲問題出在我的數據結構中。我認爲我需要將我的問題和工具存儲爲單獨的列表,然後根據我的觀點弄清楚如何合理地合併它們。 – ksimonson10