【问题标题】:Angular 2 navigating to the same route and updating route dataAngular 2导航到相同的路线并更新路线数据
【发布时间】:2017-07-12 22:56:02
【问题描述】:

有没有办法强制路由器导航到相同的路由,以便通过调用这个 canActivate 守卫两次来更新路由数据:

@Injectable()
export class LevelGuard implements CanActivate {

    private user_query_: string;
    private level_query_: string;

    constructor(private router_: Router, private query_resolver_: QueryResolver) { };

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {

        let user: string = route.params["user"];
        let level: string = route.params["level"];

        if (!user && !level) { //=> "/create"
            this.query_resolver_.setQuery({ user: this.user_query_ || "none", level: this.level_query_ || "none" });
            this.level_query_ = "";
            this.user_query_ = "";
            return true;
        }
        else if (user && !level) { //=> "/create/:user"
            this.router_.navigate(["/create"]);
            this.level_query_ = "none";
            this.user_query_ = user;
            return false;
        }
        else { //=> "/create/:user/:level"
            this.router_.navigate(["/create"]);
            this.level_query_ = level;
            this.user_query_ = user;
            return false;
        }
    };
}

如果路由已经是“/create”,那么当这个 canActivate 守卫重定向到“/create”时,它应该为“/create/:user”和“/create/:user/:level”做这件事,守卫不被称为第二次。有一个更复杂的路由方案来规避这个问题,但这会大大简化它。

编辑:解决此问题的一种方法是添加一个虚拟组件,导航到该虚拟组件,然后返回“/create”,但这会导致明显的转换并且组件不会被重用。

this.router_.navigate(["/redirect"]).then((nav) => {
    this.router_.navigate(["/create"]);
});

【问题讨论】:

    标签: angular


    【解决方案1】:

    canActivate 不适用于子路由。

    您需要使用canActivateChild 并将其设置在您的路由器上:

    路由器

    {
        path: '/create',
        loadChildren: 'yourModule#YourModule',
        canLoad: [LevelGuard ],
        canActivateChild: [LevelGuard ]
      },
    

    守卫

    只需添加您的LevelGuard:

    canActivateChild() {
        // your code here
    }
    

    【讨论】:

    • 我目前没有使用子路由,canActivate 守卫正在将路由重定向到“/create”并跟踪路由参数以将它们转发到解析器,该解析器根据那些参数。
    • 好的,现在更清晰了。实际上,没有办法对组件进行“刷新”。最直接的方法是重定向到虚拟组件。不久前我也遇到过同样的情况。
    • 啊,好吧,可能会尝试找到某种方式来重构路由,以便解析保护(或将其替换为单独的服务类)在重定向到“/create”之前获取数据。
    【解决方案2】:

    这就是我最终要做的,因为“重定向”导致 NavigationCancel 事件,我订阅了 Router.events 并跟踪最后一个导航是否有 NavigationEnd 或 NavigationCancel。尝试使用布尔标志,但找不到在正确的时间将标志重置为 false 的方法。

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
    
        let mode = route.url[0].path as "create" | "play";
    
        let user: string = route.params["user"];
        let level: string = route.params["level"];
    
        if (!user && !level) { //=> "/mode"
    
            if (this.last_navigation_outcome instanceof NavigationCancel) {
                return Observable.of(true);
            }
            else {
                user = this.user_identity_.id;
                let query = { mode, user, level: "none" };              
                this.query_resolver_.setQuery(query);
                return this.level_resolver_.resolveLevel(query).map((level) => {
                    return true;
                });
            }
        }
        else if (user && !level) { //=> "/mode/:user"
            let query = { mode, user, level: "none" }; 
            this.query_resolver_.setQuery(query);
            return this.level_resolver_.resolveLevel(query).map((level) => {
                this.router_.navigate(["/" + mode]);
                return false;
            });
        }
        else { //=> "/mode/:user/:level"
            let query = { mode, user, level };
            this.query_resolver_.setQuery(query);
            return this.level_resolver_.resolveLevel(query).map((level) => {
                this.router_.navigate(["/" + mode]);
                return false;
            });
        }
    };
    

    【讨论】:

      猜你喜欢
      • 2018-06-12
      • 2019-03-01
      • 1970-01-01
      • 2019-06-21
      • 2020-11-10
      • 2017-07-28
      • 2022-11-04
      • 2020-08-16
      • 2018-06-08
      相关资源
      最近更新 更多