Javascript 路由器出口的角度2延迟渲染

Javascript 路由器出口的角度2延迟渲染,javascript,angular,typescript,Javascript,Angular,Typescript,我正在开发一个Angular 2应用程序,其中包含多个组件,这些组件依赖于通过http服务从服务器加载的一些数据(关于用户及其角色的数据) 如果尚未加载此数据,则大多数我的路由组件在其ngOnInit()方法中都会抛出错误。数据加载并存储在注入所有组件的服务中 有没有办法延迟根组件中当前路由的呈现,直到http调用完成 否则,我将不得不在所有路由组件的ngOnInit中实现某种检查和重试机制,这将非常尴尬 我已经尝试隐藏路由器出口元素,直到呼叫结束,但这会导致一个错误,即“找不到主出口以加载xx

我正在开发一个Angular 2应用程序,其中包含多个组件,这些组件依赖于通过http服务从服务器加载的一些数据(关于用户及其角色的数据)

如果尚未加载此数据,则大多数我的路由组件在其ngOnInit()方法中都会抛出错误。数据加载并存储在注入所有组件的服务中

有没有办法延迟根组件中当前路由的呈现,直到http调用完成

否则,我将不得不在所有路由组件的ngOnInit中实现某种检查和重试机制,这将非常尴尬


我已经尝试隐藏路由器出口元素,直到呼叫结束,但这会导致一个错误,即“找不到主出口以加载xxx”

创建路由器模块时,有一个延迟路由器初始导航的选项:

RouterModule.forRoot([
    // routes here
], {
    initialNavigation: false // the propery to delay navigation
}),
稍后,可通过角度路由器触发初始导航,如下所示:

this.router.initialNavigation();

我是通过一个活跃的守卫完成的。使其工作的关键是从canActivate方法返回一个可观测值。那样的话,你可以延迟你需要的时间

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;
    }
}
然后在你的路线中声明守卫

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的文档,以供参考:

无论在哪里,服务都是一样的?如果是,您可以使用APP_INITIALIZER来处理此问题您可以使用
Resolve
类并创建一个
Resolver
作为组件的数据提供程序,它在组件初始化之前收集数据。在日志显示之前,连接页面显示:>Angular正在开发模式下运行。调用enableProdMode()以启用生产模式。client.js:67[HMR]connectedhad不得不竖起大拇指,您使用的StateService没有示例,也没有指向此类服务的链接。你的答案不完整,浪费了人们的时间。我能够找到暗示
$loading
的代码,对于未来的用户,我可以看出这是多么令人困惑。在本例中,必须用您自己的代码替换StateService。但是,您可以跟踪应用程序加载完成的时间。倾听加载完成情况。然后从
canActivate()
返回true。
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' }
];