Angular2 router.navigate() 第一次不工作

Angular2 router.navigate() not working first time

我定义了以下路由:

export const routes: Routes = [
    { path: '', component: HomeComponent, pathMatch: 'full', canActivate: [AuthGuardService] },
    { path: 'sites', component: SiteIndexComponent, resolve: { siteSummaries: SiteSummariesResolve }, canActivate: [AuthGuardService] },
    { path: 'qa-tasks', component: QaTaskIndexComponent, resolve: { investigations: InvestigationsResolve, reviews: ReviewsResolve }, canActivate: [AuthGuardService] },
    { path: 'error', component: ErrorComponent },
    { path: '**', redirectTo: '' }
];

我的应用程序的用户根据他们的角色看到完全不同的页面,包括他们的 "landing"(主页)页面。我正在使用我的 HomeComponent 根据角色将用户路由到正确的登录页面,如下所示:

export class HomeComponent implements OnInit {

    private roles: any;

    constructor(private router: Router,
        private authService: AuthService) { }

    ngOnInit() {
        var currentUser = this.authService.getCurrentUser();
        this.roles = currentUser.roles;
        this.redirect();
    }

    private redirect() {
        var route;
        if (this.inRole('site-user-role')) {
            route = 'sites';
        }
        else if (this.inRole('qa-user-role')) {
            route = 'qa-tasks';
        }
        if (route) {
            this.router.navigate([route]);
        }
        else {
            this.router.navigate(['error']);
        }
    }

    private inRole(role) {
        return _.includes(this.roles, role);
    }
}

登录后首次加载 HomeComponent 时,路由不会导航到 'sites' 路由,但奇怪的是它解析了 siteSummaries 依赖项。第一次重定向失败后,我可以导航到另一条路线,然后尝试导航到 '' 路线,它正确地重定向到 'sites' 路线。

为什么初始导航不起作用?基于其他关于 navigate() 不起作用的类似问题,我尝试将我的路线更改为“/sites”和“./sites”,但无济于事。

更新 看起来它与解决路由的依赖关系有关。如果在我的 redirect() 函数中重定向到 'error' 路由,它会在第一次成功。如果我将 resolve 添加到我的 'error' 路线,它第一次无法导航到它。奇怪的是它进行 HTTP 调用来实现依赖关系。这是一个问题,它不等待 navigate() 的承诺的 return 吗?

更新 2 这是请求的 类:

export class SiteIndexComponent implements OnInit {

    public siteSummaries: any;
    public totalRegisteredCount: number;
    public totalscreenFailedCount: number;
    public totalinProgressCount: number;

    constructor(private route: ActivatedRoute) { }

    ngOnInit() {
        this.siteSummaries = this.route.snapshot.data['siteSummaries'];
        this.totalRegisteredCount = this.getTotal('registeredCount');
        this.totalscreenFailedCount = this.getTotal('screenFailedCount');
        this.totalinProgressCount = this.getTotal('inProgressCount');
    }

    private getTotal(prop): number {
        var total = 0;
        _.forEach(this.siteSummaries, function (summary) {
            return total += summary[prop];
        });
        return total;
    }
}

@Injectable()
export class SiteSummariesResolve implements Resolve<any> {

    constructor(private sitesService: SitesService) { }

    resolve(route: ActivatedRouteSnapshot) {
        return this.sitesService.getSiteSummaries();
    }
}

getCurrentUser(): any {
    var currentUser = sessionStorage.getItem('currentUser');
    if (!currentUser) {
        return null;
    }
    return JSON.parse(currentUser);
}

更新 3 我把它扔进了我的 app.component:

private navigationInterceptor(event: RouterEvent): void {
    if (event instanceof NavigationStart) {
        console.log('started: ' + JSON.stringify(event));
    }
    if (event instanceof NavigationEnd) {
        console.log('ended: ' + JSON.stringify(event));
    }
    if (event instanceof NavigationCancel) {
        console.log('cancelled:' + JSON.stringify(event));
    }
    if (event instanceof NavigationError) {
        console.log('error:' + JSON.stringify(event));
    }
}

在加载路径失败的时候(第一次),先有NavigationStart的事件实例,然后是NavigationCancel的实例。 NavigationCancel 上的事件如下所示:{"id":2,"url":"/sites","reason":""}。如您所见,没有给出任何理由...

你不应该在构造函数中做有副作用的事情。相反,实施 ngOnInit:

class HomeComponent implements OnInit {
  ngOnInit() {
    // navigate things...
  }
}

另请参阅:

试试这个路由

import { Routes, RouterModule } from '@angular/router';


export const router: Routes = [
   { path: '',  redirectTo: 'main', pathMatch: 'full'},
  { path: 'main', component:AdminBodyComponent  },
  { path: 'admin', component:AdminComponent  },
  { path: 'posts',component:PostsComponent},
  { path: 'addposts',component:AddPostComponent}];

export const routes: ModuleWithProviders = RouterModule.forRoot(router);
step2:
inject into your .ts file
constructor(
  private router:Router,
  ...
)
step3:
this.router.navigate(['/addposts']);

我仍然不知道为什么它会取消我的路线导航,但我想出的解决方法是将 ngInit 更改为以下内容:

ngOnInit() {
    var currentUser = this.authService.getCurrentUser();
    this.roles = currentUser.roles;
    var that = this;
    setTimeout(function () { that.redirect(); }, 50);
}

在超时中包装我的重定向调用允许事情按预期工作,除了难以察觉的延迟。这似乎是某种时间问题?如果我尝试将超时设置为 20,它也不起作用。