发布于 2015-08-18 16:32:33 | 358 次阅读 | 评论: 0 | 来源: 网络整理
在一个路由过渡过程中,Ember路由器将一个过渡对象传递给过渡相关的路由的各种钩子。任何可以访问过渡对象的钩子,都可以通过调用transition.abort()来立即取消当前过渡,如果保存了该过渡对象,那么在后续可以通过调用transition.retry()来重新尝试过渡。
willTransition来阻止过渡当尝试进行过渡时,无论是通过{{link-to}},transitionTo,还是改变URL,都会在当前活动的路由上触发一个willTransition操作。这给从页节点开始,每个活动的路由一个可以决定是否发生一个过渡的机会。
假设应用当前在一个提供了复杂的表单给用户填写的路由,用户却不小心回退了。那么除非过渡被阻止,否则用户在表单上的输入将全部丢失,这会导致极差的用户体验。
下面是一个可以处理这种情形的方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
App.FormRoute = Ember.Route.extend({
actions: {
willTransition: function(transition) {
if (this.controllerFor('form').get('userHasEnteredData') &&
!confirm("Are you sure you want to abandon progress?")) {
transition.abort();
} else {
// Bubble the `willTransition` action so that
// parent routes can decide whether or not to abort.
return true;
}
}
}
});
|
当用户点击{{link-to}}助手时,或者应用使用transitionTo初始化一个过渡时,过渡将被取消并且URL也将保持不变。但是如果使用浏览器的后退按钮来退出FormRoute,或者如果用户手动的修改URL,那么在willTransition操作被调用之前,将被导航到新的URL。这样浏览器就会显示新的URl,即便在willTransition中调用了transition.abort()。
model,beforeModel或afterModel中取消过渡在异步路由中描述的model,beforeModel和afterModel钩子,每一个被调用时都传入了一个过渡对象。这让目标路由可以取消尝试进行的过渡。
1 2 3 4 5 6 7 8 |
App.DiscoRoute = Ember.Route.extend({
beforeModel: function(transition) {
if (new Date() < new Date("January 1, 1980")) {
alert("Sorry, you need a time machine to enter this route.");
transition.abort();
}
}
});
|
被取消的过渡可以在之后某一时刻进行重试。一个常见的场景就是有一个身份验证的路由,将未通过验证的用户重定向到登录页面,当用户完成登录后,将用户又定向回之前请求的路由。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
App.SomeAuthenticatedRoute = Ember.Route.extend({
beforeModel: function(transition) {
if (!this.controllerFor('auth').get('userIsLoggedIn')) {
var loginController = this.controllerFor('login');
loginController.set('previousTransition', transition);
this.transitionTo('login');
}
}
});
App.LoginController = Ember.Controller.extend({
actions: {
login: function() {
// Log the user in, then reattempt previous transition if it exists.
var previousTransition = this.get('previousTransition');
if (previousTransition) {
this.set('previousTransition', null);
previousTransition.retry();
} else {
// Default back to homepage
this.transitionToRoute('index');
}
}
}
});
|