Ember 路由終止挑戰(zhàn)和激活

2018-01-06 17:49 更新

在路由的轉(zhuǎn)換過程中,Ember路由器會(huì)通過回調(diào)(beforeModel、modelafterModel、redirect)解析一個(gè)transition對(duì)象到轉(zhuǎn)換的下一路由中。任何一個(gè)回調(diào)都可以通過傳遞過來的transition參數(shù)獲取transition對(duì)象,然后使用這個(gè)對(duì)象調(diào)用transition.abort()方法立即終止路由的轉(zhuǎn)換,如果你的程序保存了這個(gè)對(duì)象(transition對(duì)象)之后你還可以在需要的地方取出來并調(diào)用transition.retry()方法激活路由轉(zhuǎn)換這個(gè)動(dòng)作,最終實(shí)現(xiàn)路由的轉(zhuǎn)換。

1,通過調(diào)用willTransition方法阻止路由轉(zhuǎn)換

當(dāng)用戶通過{{link-to}}助手、transition方法或者直接執(zhí)行URL來轉(zhuǎn)換路由,當(dāng)前路由會(huì)自動(dòng)執(zhí)行willTransition方法。每個(gè)活動(dòng)的路由都可以決定是否執(zhí)行轉(zhuǎn)換路由。

想象一下,在當(dāng)前路由所渲染的頁面是一個(gè)比較復(fù)雜的表單,并且用戶已經(jīng)填寫了很多信息,但是用戶很可能無意中點(diǎn)擊了返回或者關(guān)閉頁面,這就導(dǎo)致了用戶填寫的信息直接丟失了,這樣的用戶體驗(yàn)并不好。此時(shí)我們可以通過使用willTransition方法阻止用戶的行為并提示用戶是否確認(rèn)離開本頁面。

為了驗(yàn)證這個(gè)特性我們需要?jiǎng)?chuàng)建好測試所需的文件。

  1. ember g controller form
  2. ember g route form

首先在controller增加測試數(shù)據(jù)。

  1. // app/controllers/form.js
  2. import Ember from 'ember';
  3. export default Ember.Controller.extend({
  4. firstName: 'chen',
  5. lastName: 'ubuntuvim'
  6. });

再創(chuàng)建一個(gè)模擬用戶填寫信息的模板。

  1. <div class="form-group">
  2. FirstName
  3. {{input type="text" class="form-control" id="exampleInputEmail1" placeholder="FirstName" value=firstName}}
  4. </div>
  5. <div class="form-group">
  6. LashName
  7. {{input type="text" class="form-control" id="exampleInputPassword1" placeholder="LashName" value=lastName}}
  8. </div>
  9. <button type="submit" class="btn btn-primary">Submit</button>
  10. <br><br>
  11. {{#link-to 'about'}}<b>轉(zhuǎn)到about</b>{{/link-to}}

關(guān)鍵部分來了,我們?cè)诼酚衫锾砑?code>willTransition方法。

  1. // app/routes/form.js
  2. import Ember from 'ember';
  3. export default Ember.Route.extend({
  4. actions: {
  5. willTransition: function(transition) {
  6. // 如果是使用this.get('key')獲取不了頁面輸入值,因?yàn)椴皇峭ㄟ^action提交表單的
  7. var v = this.controller.get('firstName');
  8. // 任意獲取一個(gè)作為判斷表單輸入值
  9. if (v && !confirm("你確定要離開這個(gè)頁面嗎??")) {
  10. transition.abort();
  11. } else {
  12. return true;
  13. }
  14. }
  15. }
  16. });

運(yùn)行:http://localhost:4200/form,先點(diǎn)擊submit提交表單,可以看到表單順利提交沒有任何問題,然后再點(diǎn)擊轉(zhuǎn)到about,你可以看到會(huì)彈出如下提示框。

run result

接著,點(diǎn)擊“取消”頁面沒有跳轉(zhuǎn),如果是點(diǎn)擊“確定”頁面會(huì)跳轉(zhuǎn)到about頁面。 再接著,把FirstName這個(gè)輸入框的內(nèi)容清空然后點(diǎn)擊“轉(zhuǎn)到about”頁面直接跳轉(zhuǎn)到了about頁面。

很多博客網(wǎng)站都是有這個(gè)功能的?。?/p>

2,在beforeModel、model、afterModel回調(diào)中阻止路由轉(zhuǎn)換

  1. beforeModel(transition) {
  2. if (new Date() > new Date('January 1, 1980')) {
  3. alert('Sorry, you need a time machine to enter this route.');
  4. transition.abort();
  5. }
  6. }

這段代碼演示的就是在beforeModel回調(diào)中使用abort方法阻止路由的轉(zhuǎn)換。代碼比較簡單我就不做例子演示了!

3,存儲(chǔ)transition對(duì)象、路由轉(zhuǎn)換重試

對(duì)于使用abort方法終止的路由可以調(diào)用retry方法重新激活。一個(gè)很典型的例子就是登陸。如果登陸成功就轉(zhuǎn)到首頁,否則跳轉(zhuǎn)回登陸頁面。 文件準(zhǔn)備工作:

  1. ember g controller auth
  2. ember g route auth
  3. ember g controller login
  4. ember g route login

下面是演示用到的代碼。

  1. // app/controllers/login.js
  2. import Ember from 'ember';
  3. export default Ember.Controller.extend({
  4. actions: {
  5. login: function() {
  6. // 獲取跳轉(zhuǎn)過來之前路由中設(shè)置的transition對(duì)象
  7. var transitionObj = this.get('transitionObj');
  8. console.log('transitionObj = ' + transitionObj);
  9. if (transitionObj) {
  10. this.set("transitionObj", null);
  11. transitionObj.retry();
  12. } else {
  13. // 轉(zhuǎn)回首頁
  14. this.transitionToRoute('index');
  15. }
  16. }
  17. }
  18. });
  1. // app/controllers/auth.js
  2. import Ember from 'ember';
  3. export default Ember.Controller.extend({
  4. userIsLogin: false
  5. });
  1. // app/routes/auth.js
  2. import Ember from 'ember';
  3. export default Ember.Route.extend({
  4. beforeModel(transition) {
  5. // 在名為auth的controller設(shè)置了userIsLogin為false,默認(rèn)是未登錄
  6. if (!this.controllerFor("auth").get('userIsLogin')) {
  7. var loginController = this.controllerFor("login");
  8. // 保存transition對(duì)象
  9. loginController.set("transitionObj", transition);
  10. this.transitionTo("login"); // 跳轉(zhuǎn)到路由login
  11. }
  12. }
  13. });
  1. 這個(gè)是登陸頁面

  1. 先執(zhí)行http://localhost:4200/auth,然后界面會(huì)自動(dòng)跳轉(zhuǎn)到login頁面,結(jié)果顯示如下:

result

可以看到URL確實(shí)是轉(zhuǎn)到login了。

  1. 執(zhí)行http://localhost:4200/login,你會(huì)發(fā)現(xiàn)頁面直接跳轉(zhuǎn)到首頁,瀏覽器控制臺(tái)打印的transitionObjundefined。由于沒有經(jīng)auth這個(gè)路由的跳轉(zhuǎn)所以獲取不到transition對(duì)象。自然就跳轉(zhuǎn)回index這個(gè)路由。


博文完整代碼放在Github(博文經(jīng)過多次修改,博文上的代碼與github代碼可能又出入,不過影響不大?。绻阌X得博文對(duì)你有點(diǎn)用,請(qǐng)?jiān)趃ithub項(xiàng)目上給我點(diǎn)個(gè)star吧。您的肯定對(duì)我來說是最大的動(dòng)力??!

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)