Angular 2+:访问中转查询参数中的路线而不是当前活动路线

Angular 2+: Accessing Route in Transit Query Params and not the Current Active Route

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

ActivatedRoute 仅显示他们所在的当前路线状态,而不显示正在运输的路线。因此,如果我在页面 'app/users/list' 上,当为 canActivatedChild 守卫提取信息时,路由快照是 'app/users/list',但我正在尝试访问 link 他们要去的地方,而不是去哪里他们来自。 (这是 Angular 应该做的;这是当前活动的快照)

问题: 如何访问一个 child 的查询参数路由,该路由在传输中应该受到保护?

场景: 我有一个用户列表 table,每个用户都可以在进入仪表板之前转到仪表板或编辑器屏幕以完成操作。因此,当用户单击用户列表 table 中的用户时,路由守卫应在继续访问仪表板之前检查用户是否具有某些属性不为 null,如果他们具有某些 null 属性,则它们是由守卫引导至编辑器页面。仪表板页面由 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
    })
   }
  }

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

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

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']);
    }
}

这可能发生在你身上,因为你试图导航到子路由而不保留实际参数 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> ,其中 oldparam 是在路由之间的过渡阶段捕获的范围变量,如第一种情况所述。

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

see my fiddle here

您不必理解所有这些,只需查看具有 this.route.queryParams.subcribe 部分的函数 CanActivateChild()

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() 函数指向。