JSRUN 用代码说话

loading、error子路由

编辑教程

loading、error子路由

在前面的Ember.js 入门指南之二十路由定义提过loading、error子路由,它们是Ember默认创建的,并在beforeModel、model、afterModel这三个回调执行完毕之前会先渲染当前路由的loading和error模板。

Router.map(function() {
  this.route('posts', function() {
      this.route('post', { path: '/:post_id'});
  });
});

每个路由都会自动生成一个loading、error路由,下面我将一一演示这两个路由的作用。

loading、error路由对应的application路由。posts_loading和posts_error对应的是posts路由。

loading子状态

Ember建议数据放在beforeModel、model、afterModel回调中获取并传递到模板显示。但是只要是加载数据就需要时间,对于Ember应用来说,在model等回调中加载完数据才会渲染模板,如果加载数据比较慢那么用户看到的页面就是一个空白的页面,用户体验很差!

Ember提供的解决办法是:在beforeModel、model、afterModel回调还没返回前先进入一个叫loading的子状态,然后渲染一个叫routeName-loading的模板(如果是application路由则对应的直接是loading、error不需要前缀)。

为了演示这效果在app/templates下创建一个posts-loading模板。如果程序正常,在渲染模板posts之前会先渲染这个模板。

<img src="assets/images/loading/loading.gif" />

然后修改路由posts.js,让model回调执行时间更长一些。

//  app/routes/posts.js

import Ember from 'ember';

export default Ember.Route.extend({

    model: function() {
        //  模拟一个延时操作,
        for (var i = 0; i < 10000000;i++) {

        }
        return Ember.$.getJSON('https://api.github.com/repos/emberjs/ember.js/pulls');
    }
});

执行http://localhost:4200/posts ,首先会看到执行的loading模板的内容, 然后才看到真正要显示的数据。

loading事件

在beforeModel、model、afterModel回调没有立即返回之前,会先执行一个名为loading的事件。

//  app/routes/posts.js

import Ember from 'ember';

export default Ember.Route.extend({

    model: function() {
        //  模拟一个延时操作,
        for (var i = 0; i < 10000000;i++) {

        }
        return Ember.$.getJSON('https://api.github.com/repos/emberjs/ember.js/pulls');
    },
    actions: {
        loading: function(transition, originRoute) {
            alert("Sorry this is taking so long to load!!");
        }
    }
});

页面刷新后会弹出一个提示框,先不点击“确定”。打开浏览器的“开发者 -> 开发者工具” ,切换到Network标签下。找到“pulls”这个请求,点击它。

此时响应的内容是空的,说明loading事件实在model回调返回之前执行了。

然后点击弹出框的“确定”,此时可以看到Response有数据了。说明model回调已经执行完毕。 注意:如果当前的路由没有显示定义loading事件,这个时间会冒泡到父路由,如果父路由也没有显示定义loading事件,那么会继续向上冒泡,一直到最顶端的路由application。

error子状态

与loading子状态类似,error子状态会在beforeModel、model、afterModel回调执行过程中出现错误的时候触发。

命名方式与loading子状态也是类似的。现在定义一个名为posts-error.hbs的模板。


<p style="color: red;">
posts回调解析出错。。。。
</p>

然后在model回调中手动添加一个错误代码。

//  app/routes/posts.js

import Ember from 'ember';

export default Ember.Route.extend({

    model: function() {
        //  模拟一个延时操作,
        for (var i = 0; i < 10000000;i++) {

        }
        var e = parseInt(value);
        return Ember.$.getJSON('https://api.github.com/repos/emberjs/ember.js/pulls');
    }
});

注意var e = parseInt(value);这句代码,由于value没有定义所以应该会报错。那么此时页面会显示什么呢??

如果演示程序没有其他问题那么你也会得到上图的结果。但是如果没有定义这个模板,那么界面上将是什么都不显示。

如果想在xxx-error.hbs模板上看到是什么错误信息,可以在模板上打印model的值。

如下:

<p style="color: red;">
posts回调解析出错。。。。
<br>
{{model}}
</p>

此时页面会显示出你的代码是什么错误。

不过相比于浏览器控制台打印的错误信息简单很多

error事件

error事件与第一点讲的loading事件也是相似的。使用方式与loading一样。个人觉得这个事件非常有用,我们可以在这个事件中根据error状态码的不同执行不同的逻辑,比如跳转到不同的路由上。

//  app/routes/posts.js

import Ember from 'ember';

export default Ember.Route.extend({

    model: function() {
        return Ember.$.getJSON('https://api.github.com/repos/emberjs/ember.js/pulls____');
    },

    actions: {
        error: function(error, transition) {
            console.log('error = ' + error.status);
            //  打印error对象里的所有属性和方法名
            for(var name in error){         
               console.log(name); 
               // console.log('属性值或者方法体==》' + error[name]);
            }    
            alert(names); 
            if (error && error.status === 400) {
                return this.transitionTo("about");
            } else if (error.status === 404) {
                return this.transitionTo("form");
            } else {
                console.log('else......');
            }
        }
    }
});

注意getJSON方法里的URL,我在URL后面随机加了一些字符,目的是让这个URL不存在。

JSRUN闪电教程系统是国内最先开创的教程维护系统, 所有工程师都可以参与共同维护的闪电教程,让知识的积累变得统一完整、自成体系。 大家可以一起参与进共编,让零散的知识点帮助更多的人。
X
支付宝
9.99
无法付款,请点击这里
金额: 0
备注:
转账时请填写正确的金额和备注信息,到账由人工处理,可能需要较长时间
如有疑问请联系QQ:565830900
正在生成二维码, 此过程可能需要15秒钟