我想拦截Sammy的所有路线变化,首先检查是否有待处理的动作。我使用sammy.before
API完成了此操作,并返回false以取消路由。这使用户保持在“页面”上,但它仍然会更改浏览器地址栏中的哈希值,并将路径添加到浏览器的历史记录中。如果我取消路线,我不想在地址栏或历史记录中,但我希望地址保持不变。
目前,要解决此问题,我可以调用window.history.back(yuk)返回历史记录中的原始位置或sammy.redirect。两者都不太理想。
有没有办法让sammy真正取消路线,使其停留在当前路线/页面上,保留地址栏,并且不会添加到历史记录中?
如果没有,是否有其他路由库可以执行此操作?
sammy.before(/.*/, function () {
// Can cancel the route if this returns false
var response = routeMediator.canLeave();
if (!isRedirecting && !response.val) {
isRedirecting = true;
// Keep hash url the same in address bar
window.history.back();
//this.redirect('#/SpecificPreviousPage');
}
else {
isRedirecting = false;
}
return response.val;
});
答案 0 :(得分:17)
如果其他人遇到这个,我就是这里的结果。我决定使用sammy的context.setLocation
功能来处理重置路径。
sammy.before(/.*/, function () {
// Can cancel the route if this returns false
var
context = this,
response = routeMediator.canLeave();
if (!isRedirecting && !response.val) {
isRedirecting = true;
toastr.warning(response.message); // toastr displays the message
// Keep hash url the same in address bar
context.app.setLocation(currentHash);
}
else {
isRedirecting = false;
currentHash = context.app.getLocation();
}
return response.val;
});
答案 1 :(得分:1)
当使用问题和答案中提供的代码时,您必须注意到您取消的路线也将在以后的所有呼叫中被阻止,因此不会再次评估routeMediator.canLeave。两次调用路由并根据当前状态取消它是不可能的。
答案 2 :(得分:0)
我可以产生与John Papa在SPA / Knockout课程中使用SammyJS时所做的相同的结果。
我使用Crossroads JS作为路由器,它依赖于Hasher JS来监听URL更改"发出"通过浏览器。
代码示例是:
hasher.changed.add(function(hash, oldHash) {
if (pageViewModel.isDirty()){
console.log('trying to leave from ' + oldHash + ' to ' + hash);
hasher.changed.active = false;
hasher.setHash(oldHash);
hasher.changed.active = true;
alert('cannot leave. dirty.');
}
else {
crossroads.parse(hash);
console.log('hash changed from ' + oldHash + ' to ' + hash);
}
});
答案 3 :(得分:0)
在重新审视一个较旧的项目并遇到类似情况之后,我想分享另一种方法,以防万一其他人被引导到这里。
所需要的基本上是一个现代的" auth guard"用于截取页面和基于凭据重定向的模式。
运行良好的是使用此处定义的Sammy.around(callback)
:
Sammy.js docs: Sammy.Application around(callback)
然后,只需执行以下操作......
(function ($) {
var app = Sammy("body");
app.around(checkLoggedIn);
function canAccess(hash) {
/* access logic goes here */
return true;
}
// Authentication Guard
function authGuard(callback) {
var context = this;
var currentHash = app.getLocation();
if (!canAccess(currentHash)) {
// redirect
context.redirect("#/login");
}
else {
// execute the route path
callback();
}
};
})(jQuery);