【问题标题】:Angular 2+: Accessing Route in Transit Query Params and not the Current Active RouteAngular 2+:在运输查询参数中访问路线而不是当前活动路线
【发布时间】:2018-06-07 04:51:52
【问题描述】:

问题: 我正在尝试访问路由保护正在检查的查询参数,而不是当前的 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
    })
   }
  }

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

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

【问题讨论】:

    标签: angular angular2-routing angular-guards


    【解决方案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']);
        }
    }
    

    【讨论】:

      【解决方案2】:

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

      对于第一种情况: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的某个树节点中,对应于路由系统的沿袭,直到最后一个计算参数。

      对于第二种情况:&lt;a [routerLink]="[{id:oldparam},'child']" [queryParams]="{ id: childparam }" &gt; link-to-child &lt;/a&gt;&lt;a [routerLink]="['.', {id:oldparam},'child']" [queryParams]="{ id: childparam }" &gt; link-to-child &lt;/a&gt;,其中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()函数指向。

      【讨论】:

        猜你喜欢
        • 2017-07-21
        • 2018-04-07
        • 2019-03-01
        • 1970-01-01
        • 2021-12-01
        • 1970-01-01
        • 2017-07-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多