想象一下,我们有一个受某种外部登录保护的视图。这是工作流程
- 用户尝试访问该页面。
- 用户被重定向到外部登录。
- 用户执行登录。
- 用户被重定向到受保护的页面。
我尝试的第一件事是设置一个钩子routerOnActivate
来检查身份验证并将用户重定向到执行重定向的登录视图。这个登录视图也是用户在登录后结束的视图,所以我需要再次重定向到受保护的页面。
- routerOnActivate HomeComponent -> 导航([“登录”])
- routerOnActivate LoginComponent -> window.location.href = redirectUri
- ...
- routerOnActivate LoginComponent -> 设置身份验证;导航([“主页”])
然而,在某些情况下,存在竞争条件,在第 2 步或第 4 步,当它再次尝试导航时导航仍未完成,最终出现错误:
EXCEPTION: TypeError: Cannot read property 'viewManager' of nullBrowserDomAdapter.logError @ angular2.dev.js:23514BrowserDomAdapter.logGroup @ angular2.dev.js:23525ExceptionHandler.call @ angular2.dev.js:1145(anonymous function) @ angular2.dev.js:14801NgZone._notifyOnError @ angular2.dev.js:5796collection_1.StringMapWrapper.merge.onError @ angular2.dev.js:5700run @ angular2-polyfills.js:141(anonymous function) @ angular2.dev.js:5719zoneBoundFn @ angular2-polyfills.js:111lib$es6$promise$$internal$$tryCatch @ angular2-polyfills.js:1511lib$es6$promise$$internal$$invokeCallback @ angular2-polyfills.js:1523lib$es6$promise$$internal$$publish @ angular2-polyfills.js:1494lib$es6$promise$$internal$$publishRejection @ angular2-polyfills.js:1444(anonymous function) @ angular2-polyfills.js:243microtask @ angular2.dev.js:5751run @ angular2-polyfills.js:138(anonymous function) @ angular2.dev.js:5719zoneBoundFn @ angular2-polyfills.js:111lib$es6$promise$asap$$flush @ angular2-polyfills.js:1305
angular2.dev.js:23514 STACKTRACE:BrowserDomAdapter.logError @ angular2.dev.js:23514ExceptionHandler.call @ angular2.dev.js:1147(anonymous function) @ angular2.dev.js:14801NgZone._notifyOnError @ angular2.dev.js:5796collection_1.StringMapWrapper.merge.onError @ angular2.dev.js:5700run @ angular2-polyfills.js:141(anonymous function) @ angular2.dev.js:5719zoneBoundFn @ angular2-polyfills.js:111lib$es6$promise$$internal$$tryCatch @ angular2-polyfills.js:1511lib$es6$promise$$internal$$invokeCallback @ angular2-polyfills.js:1523lib$es6$promise$$internal$$publish @ angular2-polyfills.js:1494lib$es6$promise$$internal$$publishRejection @ angular2-polyfills.js:1444(anonymous function) @ angular2-polyfills.js:243microtask @ angular2.dev.js:5751run @ angular2-polyfills.js:138(anonymous function) @ angular2.dev.js:5719zoneBoundFn @ angular2-polyfills.js:111lib$es6$promise$asap$$flush @ angular2-polyfills.js:1305
angular2.dev.js:23514 TypeError: Cannot read property 'viewManager' of null
at ElementInjector.getViewContainerRef (http://localhost:3000/node_modules/angular2/bundles/angular2.dev.js:12945:78)
at AppViewManager_.getViewContainer (http://localhost:3000/node_modules/angular2/bundles/angular2.dev.js:11237:68)
at http://localhost:3000/node_modules/angular2/bundles/angular2.dev.js:14555:48
at Zone.run (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:138:17)
at Zone.run (http://localhost:3000/node_modules/angular2/bundles/angular2.dev.js:5719:32)
at zoneBoundFn (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:111:19)
at lib$es6$promise$$internal$$tryCatch (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:1511:16)
at lib$es6$promise$$internal$$invokeCallback (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:1523:17)
at lib$es6$promise$$internal$$publish (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:1494:11)
at http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:243:5
说错误是重现和调试的麻烦,但最后我发现它是针对这种竞争条件的。
所以,问题是......我怎样才能确定只有在所有导航完成后才触发导航?我应该改用routerCanActivate
钩子吗?