×

EmberJS 教程

EmberJS 概述EmberJS 环境配置EmberJS 应用EmberJS 对象模型EmberJS 模板EmberJS 路由器EmberJS 组件EmberJS 模型EmberJS 视图EmberJS 控制器EmberJS 测试EmberJS 指定查询参数

Ember 对象模型

Ember 类的定义 初始化 继承Ember 类的扩展Ember 计算属性Ember 观察者Ember 数据绑定Ember 枚举Ember 第一章对象模型小结

Ember handlebars模板

Ember handlebars基础Ember handlebars条件表达式Ember handlebars遍历标签Ember handlebars显示对象键Ember handlebars属性绑定Ember {{link-to}} 助手Ember 路由 模板执行渲染顺序Ember {{action}} 助手Ember 表单元素Ember 调试助手Ember 工具类的助手Ember 第二章模板小结

Ember 路由

Ember 路由定义Ember 指定与路由关联的模型Ember 模板渲染Ember 路由重定向Ember 路由终止挑战和激活Ember loading error子路由Ember 查询参数Ember 异步路由

Ember 组件

Ember 组件定义Ember 属性传递Ember 包裹内容自定义包裹组件的HTML标签Ember 处理事件Ember action触发变化

Ember 控制器

Ember 控制器Ember 管理控制器的依赖关系

Ember 模型

Ember model简介Ember 定义模型Ember 记录查询Ember 新建、更新、删除记录Ember 设置记录到StoreEmber model的关联关系处理Ember 元数据Ember 自定义适配器Ember 自定义序列号器

Ember 测试

Ember 测试简介Ember 验收测试Ember 单元测试

Ember 路由终止挑战和激活


在路由的转换过程中,Ember路由器会通过回调(beforeModelmodelafterModelredirect)解析一个transition对象到转换的下一路由中。任何一个回调都可以通过传递过来的transition参数获取transition对象,然后使用这个对象调用transition.abort()方法立即终止路由的转换,如果你的程序保存了这个对象(transition对象)之后你还可以在需要的地方取出来并调用transition.retry()方法激活路由转换这个动作,最终实现路由的转换。

1,通过调用willTransition方法阻止路由转换

当用户通过{{link-to}}助手、transition方法或者直接执行URL来转换路由,当前路由会自动执行willTransition方法。每个活动的路由都可以决定是否执行转换路由。

想象一下,在当前路由所渲染的页面是一个比较复杂的表单,并且用户已经填写了很多信息,但是用户很可能无意中点击了返回或者关闭页面,这就导致了用户填写的信息直接丢失了,这样的用户体验并不好。此时我们可以通过使用willTransition方法阻止用户的行为并提示用户是否确认离开本页面。

为了验证这个特性我们需要创建好测试所需的文件。

ember g controller form
ember g route form

首先在controller增加测试数据。

//  app/controllers/form.js

import Ember from 'ember';

export default Ember.Controller.extend({
    firstName: 'chen',
    lastName: 'ubuntuvim'
});

再创建一个模拟用户填写信息的模板。


  <div class="form-group">
    FirstName
    {{input type="text" class="form-control" id="exampleInputEmail1" placeholder="FirstName" value=firstName}}
  </div>
  <div class="form-group">
    LashName
    {{input type="text" class="form-control" id="exampleInputPassword1" placeholder="LashName" value=lastName}}
  </div>
  <button type="submit" class="btn btn-primary">Submit</button>

<br><br>
{{#link-to 'about'}}<b>转到about</b>{{/link-to}}

关键部分来了,我们在路由里添加willTransition方法。

//  app/routes/form.js

import Ember from 'ember';

export default Ember.Route.extend({
    actions: {
        willTransition: function(transition) {
            //  如果是使用this.get('key')获取不了页面输入值,因为不是通过action提交表单的
            var v = this.controller.get('firstName');
            //  任意获取一个作为判断表单输入值
            if (v && !confirm("你确定要离开这个页面吗??")) {
                transition.abort();
            } else {
                return true;
            }
        }
    }
});

运行:http://localhost:4200/form,先点击submit提交表单,可以看到表单顺利提交没有任何问题,然后再点击转到about,你可以看到会弹出如下提示框。

run result

接着,点击“取消”页面没有跳转,如果是点击“确定”页面会跳转到about页面。 再接着,把FirstName这个输入框的内容清空然后点击“转到about”页面直接跳转到了about页面。

很多博客网站都是有这个功能的!!

2,在beforeModel、model、afterModel回调中阻止路由转换

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

这段代码演示的就是在beforeModel回调中使用abort方法阻止路由的转换。代码比较简单我就不做例子演示了!

3,存储transition对象、路由转换重试

对于使用abort方法终止的路由可以调用retry方法重新激活。一个很典型的例子就是登陆。如果登陆成功就转到首页,否则跳转回登陆页面。 文件准备工作:

ember g controller auth
ember g route auth
ember g controller login
ember g route login

下面是演示用到的代码。

//  app/controllers/login.js

import Ember from 'ember';

export default Ember.Controller.extend({
    actions: {
        login: function() {
          //  获取跳转过来之前路由中设置的transition对象
            var transitionObj = this.get('transitionObj');
            console.log('transitionObj = ' + transitionObj);
            if (transitionObj) {
                this.set("transitionObj", null);
                transitionObj.retry();
            } else {
                //  转回首页
                this.transitionToRoute('index');
            }
        }
    }
});
//  app/controllers/auth.js

import Ember from 'ember';

export default Ember.Controller.extend({
    userIsLogin: false
});
//  app/routes/auth.js

import Ember from 'ember';

export default Ember.Route.extend({
    beforeModel(transition) {
        // 在名为auth的controller设置了userIsLogin为false,默认是未登录
        if (!this.controllerFor("auth").get('userIsLogin')) {
            var loginController = this.controllerFor("login");
            // 保存transition对象
            loginController.set("transitionObj", transition);
            this.transitionTo("login");  // 跳转到路由login
        }
    }
});

这个是登陆页面
  1. 先执行http://localhost:4200/auth,然后界面会自动跳转到login页面,结果显示如下:

result

可以看到URL确实是转到login了。

  1. 执行http://localhost:4200/login,你会发现页面直接跳转到首页,浏览器控制台打印的transitionObjundefined。由于没有经auth这个路由的跳转所以获取不到transition对象。自然就跳转回index这个路由。

分类导航

关注微信下载离线手册

bootwiki移动版 bootwiki
(群号:472910771)