在导航到提供状态的过程中,Angular路由器出现问题。
我尝试使用具有canLoad()
和canActivate()
函数的自定义防护,将布尔值返回为true
,但没有任何运气。
角度docs指出以下内容:
NavigationCancel::取消导航时触发的事件。这是由于路线 导航期间警惕返回false。
由于没有从路由器跟踪中获得更多的调试信息(没有给出任何原因),我不得不在此处检查是否有修复程序,或者这是否是现有的错误。我也感谢有关在Angular 6中调试路由器的其他方法的任何信息。
控制台输出
我在here中创建了一个小项目。该项目需要访问提供者,我正在使用angular-oauth2-oidc信息库中提供的提供的OpenID Connect提供者。密码/用户名是max / geheim。
如何重现错误
更新
我怀疑这与导航到children: []
条路线有关。
答案 0 :(得分:7)
我对您的代码进行了一些调试,发现不是由于链接,身份验证保护,导航声明或模块配置,也不是因为AG6中的 router beeing flakey ,但这是因为由于.... 您正在使用的OAuth库。
但是让我解释一下。我发现正在发生以下情况:
false
会传播到整个管道并在路由器中进行订阅boolean
(甚至不是false,而是bool)作为值会导致CANCEL导航,没有任何原因。将添加一些代码引用。但总的来说,这就是发生的事情。您的oauth lib会在导航期间修改url,这会导致其被取消。警卫们不希望直接采取任何行动。
因此,通常来说,它不会因为“进入被拒绝”而被取消,就像在警卫的情况下一样,但是由于必须执行新的导航而被取消,因此它会通过取消被短路。
以下是(不是全部)相关代码:
OAuth库修改
if (!this.oidc) {
this.eventsSubject.next(new OAuthSuccessEvent('token_received'));
if (this.clearHashAfterLogin && !options.preventClearHashAfterLogin) {
location.hash = '';
}
return Promise.resolve();
}
在网址更改时触发导航:
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);
});
}
};
导航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); });
这就是传递给路由器以启动“异步”路由的内容-id是nav id(以前增加了)
Router.prototype.runNavigate = function (url, rawUrl, skipLocationChange, replaceUrl, id, precreatedState) {
此检查(在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);
}
在追赶中有几个订阅,它们都有一些管道映射等,以及已知的条件检查。
var preactivationResolveData$ = preactivationCheckGuards$.pipe(mergeMap(function (p) {
if (typeof p === 'boolean' || _this.navigationId !== id)
return of(false);
请注意,这是我之前写的内容,如果您在此处得到任何布尔值,则将false推入。由于我们这里有false
,因为以前的管道图检查失败。...
最后在链的末端
if (typeof p === 'boolean' || !p.shouldActivate || id !== _this.navigationId || !p.state) {
// debugger;
navigationIsSuccessful = false;
return;
}
结果标志设置为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);
}
NavigationCancel
,没有任何消息(最后一个参数是消息-这里是空字符串):)。
花了我很多钱,因为我不知道有角内部零件+那些血腥的管道...到处都是管道。
对于文档
NavigationCancel:取消导航时触发的事件。这个 是因为导航仪在导航期间返回了false。
好吧,他们忘记提及路由器的内部可以取消导航,因为导航队列正在累积:)
干杯!