我正在开发一个Angular 2应用程序,其中包含多个组件,这些组件依赖于通过http服务从服务器加载的一些数据(它有关用户及其角色的数据)。
如果尚未加载此数据,我的大多数路径组件都会在其ngOnInit()方法中抛出错误。数据被加载并存储在注入所有组件的服务中。
有没有办法延迟在我的root-component中呈现当前路由,直到http调用结束?
否则我将不得不在所有路由组件的ngOnInit中实现某种检查和重试机制,这将非常尴尬。
我已经尝试隐藏路由器插座元素,直到通话结束,但这会导致错误说"无法找到主插座加载xxx"
答案 0 :(得分:4)
我用CanActivate后卫完成了这项工作。使其工作的关键是从canActivate方法返回一个Observable。这样,只要你需要就可以延迟。
import { CanActivate } from '@angular/router';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Rx';
import { StateService } from '../../_services/state.service';
import { Subject } from 'rxjs/Rx';
import { Subscription } from 'rxjs/Subscription';
@Injectable()
export class LoadingGuard implements CanActivate {
constructor(private state: StateService) {}
public canActivate(): Observable<boolean> {
if (!this.state.loading$.getValue()) {
return Observable.of(true);
}
let subject = new Subject<boolean>();
let subscription = this.state.loading$.subscribe(value => {
if (!value) {
subject.next(true);
subject.complete();
subscription.unsubscribe();
}
});
return subject;
}
}
上面,StateService是一种服务,它评估当前用户并为应用程序的其余部分预缓存一些数据。它有一个名为loading$
的主题,在加载完成后返回false。
剩下的就是在app模块中声明警卫。
import { LoadingGuard } from './app/loading-guard/loading-guard';
// other imports omitted
@NgModule({
// other module properties omitted
providers: [LoadingGuard]
})
export class AppModule {}
然后在路由中声明警卫。
import { LoadingGuard } from './app/loading-guard/loading-guard';
// other imports omitted
export const rootRouterConfig: Routes = [
{ path: 'app', component: AppComponent,
canActivate: [LoadingGuard],
children: [
{ path: 'index', component: IndexComponent },
// child routes omitted
] },
{ path: 'sign-in', component: SignInComponent },
{ path: '**', redirectTo: 'sign-in' }
];
供参考,以下是CanActivate的文档: https://angular.io/docs/ts/latest/api/router/index/CanActivate-interface.html