2

问题:我正在尝试访问路由保护正在检查的查询参数,而不是当前的 url 快照查询参数。

ActivatedRoute 只显示他们当前的路由状态,而不是正在传输的路由状态。因此,如果我在“app/users/list”页面上,当为 canActivatedChild 守卫拉取信息时,路由快照是“app/users/list”,但我试图访问他们要去的链接,而不是在哪里他们来自。(这是 Angular 应该做的;这是当前活动的快照)

问题:如何访问假设要防范的正在传输的孩子的查询参数路由?

场景:我有一个用户的列表,每个用户在进入仪表板之前可以去仪表板或编辑器屏幕完成。因此,当用户从用户列表表中单击用户时,路由守卫应该在进入仪表板之前检查用户是否有某些属性不为空,如果他们有一些空属性,则由守卫指导到编辑器页面。仪表板页面由 canActivatedChild 保护器保护,该保护器根据用户是否具有所有可用信息来决定是否可以在仪表板中显示用户的详细信息,如果没有,则将其重定向到编辑器以完成。

 // The Link
 this.router.navigate(['/dashboard', { id: userId }])


 // The Guard
 @Injectable()
 export class CanShowUserDashboard implements CanActivateChild {

   constructor(
     private _router: Router,
     private _route: ActivatedRoute
   ) {}

   canActivateChild() {
    this._route.queryParams.subscribe((next) => {
       let queryParams = next.id;
       // queryParams is undefined
    })
   }
  }

目标 从仪表板链接获取查询参数,而不是当前活动用户的列表页面。

我得到的唯一解决方案? 正在考虑将用户传递给服务,并让守卫访问服务以提取信息。

4

2 回答 2

1

canActivateChild函数接收ActivatedRouteSnapshot子路由的第一个参数。

export interface CanActivateChild {
    canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean;
}

因此,您可以从childRoute参数中获取用户 ID。

@Injectable()
export class CanShowUserDashboard implements CanActivateChild {

    canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
         // prints the value of userId
         console.log(childRoute.queryParams['id']);
    }
}
于 2018-06-06T01:10:16.470 回答
0

这可能发生在您身上,因为您试图导航到子路由而不保留实际参数 sain 如下所示this.router.navigate(['child-one', {id:'childparameter'}],{ relativeTo: this.route });,或者从模板超链接之类<a [routerLink]="['child']" [queryParams]="{ id: childparam}" > link-to-child </a>的,在这两种情况下,即使路由调用与实际路由相关,浏览器也会破坏父查询字符串。 ,以防止它使用:

对于第一种情况 : this.router.navigate(['/parent' , { id: this.router.routerState.snapshot._root.children[0].value.url[0].parameters['id'] } ,'child' , {id:this.route.snapshot.queryParams['id']} ]);,它保留对象的某个树节点中的第一个参数router.routerState.snapshot._root,对应于路由系统的沿袭,直到最后一个计算参数。

对于第二种情况 :<a [routerLink]="[{id:oldparam},'child']" [queryParams]="{ id: childparam }" > link-to-child </a><a [routerLink]="['.', {id:oldparam},'child']" [queryParams]="{ id: childparam }" > link-to-child </a>, whereoldparam是在路由之间的过渡阶段捕获的范围变量,如第一种情况中所述。

请注意,我是_root.children[0]任意使用的,您也可以使用_root.value.firstChild,这将具有相同的输出。

在这里看我的小提琴

您不必了解所有这些,只需查看CanActivateChild()具有this.route.queryParams.subcribe部分的功能即可。

decide(a,b){

   if(a.children[0]!==undefined){
      console.log('haschild');
      return a.value.url[0].parameters['id'];}
    else
    {
      console.log('dosnt have child');
      return b;
    }
  }

CanActivateChild () {

    console.log("decide");

    this.route.params.subscribe((next) => {
       console.log("logging parent")
       console.log( this.decide(this.router.routerState.snapshot._root.children[0],next.id));
    });
  }

如果路由调用是嵌套的,则此函数记录传递查询参数,如果地址是无子的,则记录最后一个订阅参数。可以通过decide()函数来​​指出。

于 2018-06-06T11:13:00.827 回答