我有一个Issue对象,其中一个属性是Tool对象的数组。问题和工具是我数据库中的两个不同的表。
在我的issues-log.component中,我正在调度一个操作来搜索与我的搜索查询匹配的问题。这很好用。
我接下来要做的就是获取问题列表,并针对每个问题ID,将其传递给我的工具服务,以便我可以获得与该问题相关的工具。
我能够正常工作的方法是添加另一个侦听ISSUE.SEARCH.COMPLETE操作的效果。然后我遍历了工具服务中的一系列问题,以便我可以为每个问题ID调用API服务,并将tools属性添加到该问题中。这在某些方面似乎是错误的。一个是对于大型问题列表,所有工具加载需要很长时间,如果我尝试启动另一个问题搜索,我必须等待工具在我的应用响应之前从前一个加载。第二,当我的工具API只需要一个问题ID来获取与该问题相关的工具列表时,将整个问题数组传递到工具服务似乎是错误的。这并不能使我的工具服务在我的应用程序的其他位置轻松重复使用。
在我开始获取与每个问题ID相关联的工具之前,我宁愿不要等到我的API调用才能获得问题列表。是否可以在我的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 :(得分:1)
由于您需要立即访问问题的结果,在使用这些问题的数据进行其他异步请求之前,您可能希望使用某种RxJS Subject
。
您可以观察该主题的问题,并订阅所有最终通话结果的观察结果。
概念分解:
因此,您必须使用此方法订阅两个可观察的流。
这是一个简单,人为的例子:
@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
});
}
}
这对你有用吗?