我试图在 ngOnInit()
中调用一个函数并将其提供两个值。因此,这是我尝试在ngOnInit
内部调用的函数:
this.complexWordIdentification(this.postIWant, this.theHardWords);
这里的问题是this.postIWant
和this.theHardWords
本身在ngOnInit
中得到了解决,如下所示,这导致了错误。现在,我如何调用 this.complexWordIdentification(this.postIWant, this.theHardWords);
并将其输入这些值而又不会出错?
我一直在考虑等待功能吗?但是我无法弄清楚,请问对此有何建议?
这是我的ngOnInit
:
ngOnInit() {
this.isLoading = true;
this.wordsLoaded = false;
this.postLoaded = false;
this.form = new FormGroup({
annotation: new FormControl(null, {
validators: [
Validators.required,
Validators.minLength(8),
Validators.maxLength(250)
]
})
});
this.id = this.route.snapshot.paramMap.get('postId');
this.annotationService.getWords();
this.annotationSub = this.annotationService
.getWordUpdateListener()
.subscribe((thewords: ComplexWord[]) => {
this.thewords = thewords;
this.thewords.map(word => {
this.theHardWords.push(word.word);
this.wordWithAnnotation.push(word);
});
this.wordsLoaded = true;
this.isLoading = this.postLoaded && this.wordsLoaded;
});
this.postsService.getPosts();
this.postsSub = this.postsService
.getPostUpdateListener()
.subscribe((posts: Post[]) => {
this.posts = posts;
this.posts.map(post => {
if (post.id === this.id) {
this.postIWant = post.fileText;
}
});
this.postLoaded = true;
this.isLoading = !(this.postLoaded && this.wordsLoaded);
});
this.role = this.authService.getUserRole();
this.userIsAuthenticated = this.authService.getIsAuth();
this.authStatus = this.authService
.getAuthStatus()
.subscribe(isAuthenticated => {
this.userIsAuthenticated = isAuthenticated;
this.role = this.authService.getUserRole();
});
}
如果有人能指出我正确的方向,那将非常好,因为我在这一领域经验不足。目前,我不得不在this.complexWordIdentification(this.postIWant, this.theHardWords);
之外调用ngOnInit
来避免该错误,但是显然,我想自动调用它。
答案 0 :(得分:5)
forkJoin
将两个订阅合并为一个订阅,并返回其结果数组。当您需要多个来源的数据才能完成组件的加载时,在ngOnInit
中使用它非常有用。
https://www.learnrxjs.io/operators/combination/forkjoin.html
import { Observable } from "rxjs/Observable";
Observable.forkJoin(
this.annotationService.getWordUpdateListener(),
this.postsService.getPostUpdateListener()
).subscribe((data) => {
// data[0] result from getWordUpdateListener
this.thewords = data[0];
this.thewords.map(word => {
this.theHardWords.push(word.word);
this.wordWithAnnotation.push(word);
});
this.wordsLoaded = true;
// data[1] result from getPostUpdateListener
this.posts.map(post => {
if (post.id === this.id) {
this.postIWant = post.fileText;
}
});
this.postLoaded = true;
this.isLoading = false;
this.complexWordIdentification(this.postIWant, this.theHardWords);
}, (err) => {
// error handling
});
edit:在RXJS 5及以下版本中添加了可观察到的导入语句
编辑:RXJS 6更新,更改导入语句
import { forkJoin} from 'rxjs';
forkJoin(this.annotationService.getWordUpdateListener(),
this.postsService.getPostUpdateListener()
).subscribe((data) => { \\do stuff}, (err) => { \\ do error stuff}
答案 1 :(得分:1)
因为您一次需要两个独立流中的数据,所以需要以某种方式组合流。下面是一个示例示例:
this.annotationService.getWordUpdateListener().pipe(
switchMap(thewords => {
return this.postsService.getPostUpdateListener().pipe(
map(posts => ({ thewords, posts }))
);
}),
)
.subscribe(({ thewords, posts }) => {
this.complexWordIdentification(posts, thewords);
});
答案 2 :(得分:0)
如果同时需要this.postIWant,this.theHardWords组件初始化,则可以使用角度解析,即https://angular.io/api/router/Resolve
示例:-
class Backend {
fetchTeam(id: string) {
return 'someTeam';
}
}
@Injectable()
class TeamResolver implements Resolve<Team> {
constructor(private backend: Backend) {}
resolve(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<any>|Promise<any>|any {
return this.backend.fetchTeam(route.params.id);
}
}
@NgModule({
imports: [
RouterModule.forRoot([
{
path: 'team/:id',
component: TeamCmp,
resolve: {
team: TeamResolver
}
}
])
],
providers: [TeamResolver]
})
class AppModule {}