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,它也不起作用。
我定义了以下路由:
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,它也不起作用。