Gje*_*t G 6 angular angular-router angular-guards
我在导航到提供状态的过程中遇到了Angular路由器的问题.
我试过使用自定义后卫canLoad()和canActivate()功能返回布尔值true没有任何运气.
Angular 文档声明如下:
NavigationCancel:取消导航时触发的事件.这是由于Route Guard在导航期间返回false.
由于我没有从路由器跟踪中获得更多调试信息(没有给出任何理由),我被迫在这里检查是否存在修复,或者这是否是现有错误.我也很欣赏有关在Angular 6中调试路由器的其他方法的任何信息.
控制台输出
我在这里创建了一个小项目.该项目需要访问提供者,我正在使用angular-oauth2-oidc存储库中提供的提供的OpenID Connect提供程序.密码/用户名是max/geheim.
如何重现错误
更新
我怀疑它与导航到children: []路线有关.
Ant*_*sss 12
我在你的代码中进行了一些调试,我发现这不是因为链接,auth后卫,导航声明或模块配置,也不是AG6中的路由器,但它是因为..... OAuth lib you正在使用.
但让我解释一下.我发现以下情况正在发生:
false因此在整个管道中传播单个并在路由器中进行订阅boolean(甚至是假的,但是bool)作为管道中的值导致CANCEL导航没有任何理由.我添加了一些代码参考.但总的来说,这就是发生的事情.你的oauth lib在导航过程中修改url并导致它被取消.卫兵与此直截了当地没有任何关系.
所以一般情况下 - 它没有被取消,因为"访问被拒绝",就像警卫一样,但它被取消,因为必须执行新的导航,所以它被取消短路.
这是(不是全部)相关代码:
OAuth lib修改
if (!this.oidc) {
this.eventsSubject.next(new OAuthSuccessEvent('token_received'));
if (this.clearHashAfterLogin && !options.preventClearHashAfterLogin) {
location.hash = '';
}
return Promise.resolve();
}
Run Code Online (Sandbox Code Playgroud)
网址上的导航触发更改:
Router.prototype.setUpLocationChangeListener = function () {
var _this = this;
// Don't need to use Zone.wrap any more, because zone.js
// already patch onPopState, so location change callback will
// run into ngZone
if (!this.locationSubscription) {
this.locationSubscription = this.location.subscribe(function (change) {
var rawUrlTree = _this.parseUrl(change['url']);
var source = change['type'] === 'popstate' ? 'popstate' : 'hashchange';
if(this.rou)
var state = change.state && change.state.navigationId ?
{ navigationId: change.state.navigationId } :
null;
setTimeout(function () { console.error("FROM LOCATION SUB");_this.scheduleNavigation(rawUrlTree, source, state, { replaceUrl: true }); }, 0);
});
}
};
Run Code Online (Sandbox Code Playgroud)
导航ID修改 - 立即发生:
var id = ++this.navigationId;
console.error("ANOTHER SCHEDULED LOL LOL LOL!!!");
this.navigations.next({ id: id, source: source, state: state, rawUrl: rawUrl, extras: extras, resolve: resolve, reject: reject, promise: promise });
// Make sure that the error is propagated even though `processNavigations` catch
// handler does not rethrow
return promise.catch(function (e) { return Promise.reject(e); });
Run Code Online (Sandbox Code Playgroud)
这是传递给路由器以启动"异步"路由的内容 - id是nav id(先前增加)
Router.prototype.runNavigate = function (url, rawUrl, skipLocationChange, replaceUrl, id, precreatedState) {
Run Code Online (Sandbox Code Playgroud)
这个检查(在runNav中)首先因为id改变而失败,所以2!== 3 - FALSE被返回到管道
var preactivationCheckGuards$ = preactivationSetup$.pipe(mergeMap(function (p) {
if (typeof p === 'boolean' || _this.navigationId !== id) //NAVIGATION ID CHANGES HERE!
{
console.warn("PREACTIVATE GUARD CHECK ");
console.log(p);
// debugger;
return of(false);
}
Run Code Online (Sandbox Code Playgroud)
在chaing中还有几个订阅,它们都有一些管道映射等以及已知的条件检查.
var preactivationResolveData$ = preactivationCheckGuards$.pipe(mergeMap(function (p) {
if (typeof p === 'boolean' || _this.navigationId !== id)
return of(false);
Run Code Online (Sandbox Code Playgroud)
请注意,这是我之前写的,如果你在这里得到任何booean,那么就会向前推进false.因为我们已经false在这里因为先前的管道图中的检查失败了....
最后在链的末尾
if (typeof p === 'boolean' || !p.shouldActivate || id !== _this.navigationId || !p.state) {
// debugger;
navigationIsSuccessful = false;
return;
}
Run Code Online (Sandbox Code Playgroud)
结果标志设置为false,这会导致
.then(function () {
if (navigationIsSuccessful) {
_this.navigated = true;
_this.lastSuccessfulId = id;
_this.events
.next(new NavigationEnd(id, _this.serializeUrl(url), _this.serializeUrl(_this.currentUrlTree)));
resolvePromise(true);
}
else {
_this.resetUrlToCurrentUrlTree();
_this.events
.next(new NavigationCancel(id, _this.serializeUrl(url), ''));
resolvePromise(false);
}
Run Code Online (Sandbox Code Playgroud)
NavigationCancel 没有任何消息(最后一个参数是消息 - 这里的emtpy字符串),你知道的很好:).
我花了很多钱,因为我不知道有角度的内部结构+那些血腥的管道......到处都是管道.
至于文档
NavigationCancel:取消导航时触发的事件.这是由于Route Guard在导航期间返回false.
好吧,他们忘了提到内部路由器可以取消导航是有队列的导航建立:)
干杯!