hszy00232/developExperience

构建Backbone.js应用

Opened this issue · 4 comments

在该应用中使用视图、集合,子视图、模型、事件绑定、AMD和Require.js
功能描述:首页,图片详情页
首页:显示列表,点击列表项进入相应详情页,点击add,显示列表项名称
详情页:显示图片和标题

AMD允许我们把开发代码组织成模块,管理它们的依赖,异步加载它们。
index.html加载几个依赖库jquery.js,underscore.js,backbone.js,require.js,apple-app.js是整个应用的入口
index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="../jquery/jquery-1.9.1.js"></script>
    <script src="../bower_components/underscore/underscore.js"></script>
    <script src="../bower_components/backbone/backbone.js"></script>
    <script src="../bower_components/requirejs/require.js"></script>
    <script src="apple-app.js"></script>
</head>
<body>

</body>
</html>

apple-app.js

require([
    'apple-item.tpl',
    'apple-home.tpl',
    'apple-spinner.tpl',
    'apple.tpl',
    'apple-item.view',
    'apple-home.view',
    'apple.view',
    'apple'
],function(appleItemTpl,appleHomeTpl,appleSpinnerTpl,appleTpl,appleItemView,homeView,appleView,Apples){
    var appleData = [
        {
            name:'tu1',
            url:'http://p3.qhimg.com/t017d786ae710c2e7f2.png'
        },
        {
            name:'tu2',
            url:'http://p1.qhimg.com/d/inn/6ea5ef05/logo/haosou_music_logo_1x.png'
        }
    ];
    var app;
    // 路由器
    var router = Backbone.Router.extend({
        routes:{
            "":'home',
            "apples/:appleName":'loadApple'
        },
        initialize:function(){
            var apples = new Apples();
            // 自动创建模型
            apples.reset(appleData);
            this.homeView = new homeView({collection:apples});
            this.appleView = new appleView({collection:apples});
        },
        home:function(){
            this.homeView.render();
        },
        loadApple:function(appleName){
            this.appleView.loadApple(appleName);
        }
    });
    $(document).ready(function(){
        app = new router;
        Backbone.history.start();
    })
});

*.tpl.js是模板文件,define([...],function(...){...});定义模块
apple-item.tpl.js用做子视频的模板

define(function(){
    return '<a href="#apples/<%=name%>" target="_blank">'
        +'<%=name%>'
        +'</a>&nbsp;<a href="#" class="add-to-car">buy</a>'
});

apple-home.tpl.js用做视频的模板

define(function(){
    return 'Apple data:'
    +'<ul class="apples-list"></ul>'
    +'<div class="cart-box"></div>'
});

apple-spinner.tpl.js用做load的模板

define(function(){
    return '<img src="http://static.oschina.net/uploads/space/2014/1014/174215_mMIM_5189.gif"/>'
});

apple.tpl.js用做详情页模板

define(function(){
    return '<figure>'+
        '<img src="<%=attributes.url%>"/>'+
        '<figcaption><%=attributes.name%></figcaption>'+
        '</figure>'
});

*.view.js视图
apple-item.view.js 子视图,依赖子视图模板apple-item.tpl.js

define(['apple-item.tpl'],function(appleItemTpl){
    return Backbone.View.extend({
        tagName:'li',
        template:_.template(appleItemTpl),
        events:{
            // 事件 + jQuery选择器:函数名
            'click .add-to-car':'addToCart'
        },
        render:function(){
            this.$el.html(this.template(this.model.attributes));
        },
        addToCart:function(){
            this.model.collection.trigger('addToCart',this.model);
        }
    });
});

apple-home.view.js 视图,依赖home模板app-home.tpl.js,子视图app-item.view.js

define(['apple-home.tpl','apple-item.view'],function(appleHomeTpl,appleItemView){
    return Backbone.View.extend({
        el:'body',
        listEl:'.apples-list',
        cartEl:'.cart-box',
        initialize:function(){
            this.$el.html(this.template);
            this.collection.on("addToCart",this.showCart,this);
        },
        template:_.template(appleHomeTpl),
        render:function(){
            //存储上下文
            var view = this;
            //collection:model集合,在new Router时传入
            this.collection.each(function(apple){
                var appleSubView = new appleItemView({model:apple});
                appleSubView.render(); // 渲染subView模板
                $(view.listEl).append(appleSubView.$el);
                //把渲染好的子视图里的jQuery对象添加到列表DOM元素里
            });
        },
        showCart:function(appleModel){
            $(this.cartEl).append(appleModel.attributes.name+'<br/>');
        }
    });
});

apple.view.js 详情页视图,依赖详情模板apple.tpl.js,load模板apple-spinner.tpl.js

define(['apple.tpl','apple-spinner.tpl'],function(appleTpl,appleSpinnerTpl){
    return Backbone.View.extend({
        initialize:function(){
            //创建模型
            this.model = new (Backbone.Model.extend());
            //兼听model变化
            //on(event,actions,context)
            this.model.on('change',this.render,this);
            //自定义spinner事件:显示loading
            this.on('spinner',this.showSpinner,this);
        },
        template:_.template(appleTpl),
        tempSpinner:appleSpinnerTpl,
        loadApple:function(appleName){
            this.trigger('spinner'); //手动触发spinner事件
            var view = this; // 保存上下文this
            // 模拟从服务器端请求数据
            setTimeout(function(){
                // model设置数据源:把相应数据的attibutes赋值给model
                // 因为model发生变化会触发change事件
                view.model.set(view.collection.where({name:appleName})[0].attributes);
            },1000);
        },
        render:function(){
            var appleHTML = this.template(this.model);
            $('body').html(appleHTML);
        },
        showSpinner:function(){
            $('body').html(this.tempSpinner);
        }
    });
});

apple.js定义集合
define(function(){
return Backbone.Collection.extend({});
});