路由器插座的Angular 2延迟渲染
Posted
技术标签:
【中文标题】路由器插座的Angular 2延迟渲染【英文标题】:Angular 2 delay rendering of router-outlet 【发布时间】:2017-04-23 12:59:44 【问题描述】:我正在开发一个具有多个组件的 Angular 2 应用程序,这些组件依赖于通过 http 服务从服务器加载的一些数据(它是关于用户及其角色的数据)。
如果此数据尚未加载,我的大多数路由组件都会在其 ngOnInit() 方法中抛出错误。数据被加载并存储在注入所有组件的服务中。
有没有办法在我的根组件中延迟渲染当前路由,直到 http 调用完成?
否则我将不得不在所有路由组件的 ngOnInit 中实现某种检查和重试机制,这将非常尴尬。
我已经尝试在调用完成之前隐藏 router-outlet 元素,但这会导致错误提示“无法找到要加载 xxx 的主出口”
【问题讨论】:
服务哪里都一样?如果是,您可以使用 APP_INITIALIZER 来处理此问题 您可以使用Resolve
类并创建一个Resolver
作为组件的数据提供者,它会在您的组件初始化之前收集数据。
【参考方案1】:
创建Router模块时有一个延迟Router初始导航的选项:
RouterModule.forRoot([
// routes here
],
initialNavigation: false // the propery to delay navigation
),
稍后可以通过 Angular Router 触发初始导航,如下所示:
this.router.initialNavigation();
【讨论】:
连接页面先于日志显示: > Angular 正在开发模式下运行。调用 enableProdMode() 以启用生产模式。 client.js:67 [HMR] 已连接【参考方案2】:我使用 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。
剩下的就是在应用模块中声明守卫。
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
【讨论】:
不得不拒绝,您使用 stateSevice 没有示例或链接到此类服务。您的答案不完整,浪费了人们的时间。 我能够找到暗指$loading
的代码,供未来用户使用 levelup.gitconnected.com/…
我可以看出这是多么令人困惑。在此示例中,必须将 StateService 替换为您自己的代码。但是,您会跟踪应用程序何时完成加载。监听加载完成。然后从canActivate()
返回true。以上是关于路由器插座的Angular 2延迟渲染的主要内容,如果未能解决你的问题,请参考以下文章
Angular Universal 不在路由器插座内呈现内容