2014/08/08 – Backbonejs

[来自: Backbone.js 开发秘笈 第5章]

Event API:

(function ($) {
    //define -------------------------
    var obj = {};
    var obj2 = {
        commonEvent: function () {
            window.document.title = new Date().toString();
        }
    };
    //扩展对象包含事件
    _.extend(obj, Backbone.Events);
    _.extend(obj2, Backbone.Events);
    //绑定事件  [ once() 方法绑定的行为只触发一次]
    /* Backbone.Events 会把回调函数保持在一个名为 _events 的关联数组中,随后在调用 trigger() 方法时,它会迭代地执行事件上所有的回调函数。 */
    obj.on('test', function (args) {
        window.document.title = args;
    });

    $(function () {
        //apply ------------------------------------------------
        //触发事件
        obj.trigger('test', "Test Title");
        //取消回调函数
        obj.off('test');
        //obj.off('test',/* 参数为要取消的指定回调函数 */);
        //obj.off(null,/* 参数为所以事件中要取消的指定回调函数 */);
        //obj.off();取消所有

        //侦听其他对象上的事件
        obj2.listenTo(obj, 'click', obj2.commonEvent);
        obj.trigger('click');
        //取消侦听
        obj2.stopListening(obj);
        //obj2.stopListening();//取消所有
    });
})(jQuery);

1. 处理 Backbone 对象事件

(function ($) {
    //define -----------------------------
    var model = new Backbone.Model({
        firstName: 'John',
        lastName: 'Doe',
        age: 20
    });
    model.on('change', function (model) {
        if (model.hasChanged('age')) {//是否更改了 age 属性
            var oldAge = model.previous('age');//获取更改前 age 属性
            var oldAttrs = model.previousAttributes();//获取所以变化前的属性
            var upAttrs = model.changedAttributes();//获取所有变化的属性
        }

    });
    /* 内置事件:    http://backbonejs.org/#Events-catalog
       模型事件 -
        change(model, options)
        change:[attribute](model, value, options)
        destroy(model, collection, options)
        invalid(model, error, options)
        error(model, xhr, options)
        sync(model, resp, options)
       集合事件 -
        add(model, collection, options)
        remove(model, collection, options)
        reset(collection, options)
        sort(collection, options)
        sync(collection, resp, options)
       路由事件 -   //注:当执行存储操作时,会触发 route 事件
        route:[name](params)    //name 路由名
        route(router, route, params)    //Backbone 的 history 对象或者路由器会触发事件
       
       all 所以事件
    */

    $(function () {
        //apply ---------------------------------
        model.set('age', 22);
        model.set({
            firstName: 'Yo',
            lastName: 'Yo'
        }, {
            silent: true//不触发 change 事件
        });
    });
})(jQuery);
View Code

2. 模型绑定到视图(视图响应模型的改变)

(function ($) {
    //define -----------------------------------------
    var UserView = Backbone.View.extend({
        el: 'body',
        render: function () {
            $(this.el).html("<p>" + this.model.get('name') + "</p>");
            $('body').append("<input type='button' value='Modify' οnclick='updateUserName();'>");
        },
        initialize: function () {
            //侦听模型变化
            this.listenTo(this.model, 'change', this.render, this);
        }
    });

    $(function () {
        //apply ----------------------------
        var userModel = new Backbone.Model({
            id: 1,
            name: 'yoyo'
        });
        var userView = new UserView({
            model: userModel
        });
        window.updateUserName = function () {
            userModel.set('name', new Date().toString());
        };
        userView.render();
    });
})(jQuery);
View Code

3. 集合绑定到视图

(function ($) {
    //define ------------------------------
    var UserModel = Backbone.Model.extend();
    var UserCollection = Backbone.Collection.extend({ model: UserModel });
    var UserListItemView = Backbone.View.extend({
        tagName: 'li',
        events: {
            'click a': 'clickCurrent'
        },
        initialize: function () {
            //侦听 Model 的变化
            this.listenTo(this.model, 'destroy', function () {
                this.remove();//删除视图
            }, this);
            this.listenTo(this.model, 'change', function () {
                this.render();//刷新视图
            }, this);
        },
        render: function () {
            $(this.el).html("<a href='javascript:;'>" + this.model.get('name') + "</a>");
            return this;
        },
        clickCurrent: function () {
            //触发 Model 选中事件
            this.model.trigger('select', this.model);
        }
    });
    var UserListView = Backbone.View.extend({
        tagName: 'ul',
        initialize: function () {
            //侦听 Collection 添加 Model 事件
            this.listenTo(this.collection, 'add', function (model) {
                //视图添加新 Model
                $(this.el).append(new UserListItemView({ model: model }).render().el);
            }, this);
        },
        render: function () {
            $(this.el).html(_.map(this.collection.models, function (model) {
                return new UserListItemView({ model: model }).render().el;
            }));
            return this;
        }
    });
    var UserFormView = Backbone.View.extend({
        tagName: 'div',
        render: function () {
            $(this.el).html("<label>name:</label><input type='textbox' value='" + (this.model ? this.model.get('name') : '') + "' class='txtName' />" +
                "<input type='button' value='Add' class='btnAdd'><input type='button' value='Update' class='btnUpdate'><input type='button' value='Remove' class='btnRemove'>");

            //cache element
            this.txtName = $(this.el).find("input[class='txtName']")[0];

            return this;
        },
        refresh: function () {

            this.txtName.value = this.model ? this.model.get('name') : "";
        },
        events: {
            "click input[class='btnAdd']": "add",
            "click input[class='btnUpdate']": "update",
            "click input[class='btnRemove']": "remove"
        },
        add: function () {
            if (this.txtName.value.length !== 0) {
                this.model = new UserModel({
                    name: this.txtName.value
                });
                this.collection.add(this.model);
            }
        },
        update: function () {
            if (this.model) {
                this.model.set('name', this.txtName.value);
            }
        },
        remove: function () {
            if (this.model) {
                this.model.destroy();
                this.model = null;
                this.refresh();
            }
        }
    });
    var ShowView = Backbone.View.extend({
        el: 'body',
        render: function () {
            $(this.el).html([
                new UserListView({ collection: this.collection }).render().el,
                $("<p>---------------</p>")[0],
                (this.currentFormView = new UserFormView({ model: null, collection: this.collection })).render().el
            ]);
            return this;
        },
        initialize: function () {
            //添加侦听 Model 选中事件
            _.each(this.collection.models, function (model) {
                this.listenTo(model, 'select', this.selectModel, this);
            }, this);
            this.listenTo(this.collection, 'add', function (model) {
                this.listenTo(model, 'select', this.selectModel, this);
            }, this);
        },
        selectModel: function (model) {
            this.currentFormView.model = model;
            this.currentFormView.refresh();
        }
    });

    $(function () {
        //instance --------------------------
        var users = new UserCollection([
            { name: '123' },
            { name: '456' },
            { name: '789' },
            { name: '012' }
        ]);
        var mainView = new ShowView({ collection: users });

        //apply ---------------------------------
        mainView.render();
    });

})(jQuery);
View Code

4. 双向绑定

(function ($) {
    //依赖 backbone.stickit.js
    //https://github.com/nytimes/backbone.stickit

    //define -----------------------------------
    var TitleView = Backbone.View.extend({
        tagName: 'p',
        /* 设置绑定关系 */
        bindings: {
            "span[class='appName']": 'name',//简写
            "span[class='appAge']": {
                observe: 'age',
                onGet: function (value, options) {//重写 getter 方法
                    return "Welcome " + value;
                }
            }
        },
        render: function () {
            $(this.el).html("<span class='appName'>" + this.model.get('name') + "</span><span class='appAge'>" + this.model.get('age') + "</span>");

            //call binding method
            this.stickit();

            return this;
        }
    });
    var EditView = Backbone.View.extend({
        tagName: 'div',
        bindings: {
            "input[class='appName']": {
                observe: 'name',
                onSet: function (value, options) {//重写 setter 方法
                    return "Mr." + value;
                },
                /* 重写更新方法
                    update($el,value,model,options)
                    afhterUpdate($el,value,options)
                    updateMethod:'html' (默认 text() 方法)
                */
                events: ['blur']//修改事件的侦听
            },
            "input[class='appAge']": 'age'
        },
        render: function () {
            $(this.el).html("<label>Name:</label><input class='appName' type='textbox' value='" + this.model.get('name') + "' /><label>Age:</label><input class='appAge' type='textbox' value='" + this.model.get('age') + "' />");

            //call binding method
            this.stickit();

            return this;
        }
    });

    var MainView = Backbone.View.extend({
        el: 'body',
        render: function () {
            $(this.el).html([new TitleView({ model: this.model }).render().el, new EditView({ model: this.model }).render().el]);
            return this;
        }
    });

    $(function () {
        //instance ----------------
        var modelInstance = new Backbone.Model({ name: 'YoYo', age: 22 });
        var mainView = new MainView({ model: modelInstance });

        //apply --------------------
        mainView.render();
    });
})(jQuery);
View Code

5. 绑定下拉列表

(function ($) {
    //依赖 backbone.stickit.js
    //https://github.com/nytimes/backbone.stickit

    //define ------------------------------
    var StateModel = Backbone.Model.extend();
    var TitleView = Backbone.View.extend({
        tagName: 'p',
        render: function () {
            $(this.el).html("<span>" + this.collection[this.model.get('selID') - 1].name + "</span>");

            this.stickit();

            return this;
        },
        bindings: {
            'span': {
                observe: 'selID',
                onGet: function (value, options) {//重写 getter 方法
                    return this.collection[value - 1].name;
                }
            }
        }
    });
    var StateView = Backbone.View.extend({
        el: 'body',
        render: function () {
            $(this.el).html("<select class='selState'></select>");

            this.stickit();

            return this;
        },
        bindings: {
            'select.selState': {
                observe: 'selID',
                selectOptions: {//select 参数集合对象
                    //集合对象
                    collection: function () {
                        return this.collection;
                    },
                    labelPath: 'name',
                    valuePath: 'id'
                }
            }
        }
    });
    //instance ---------------------------------
    var stateModel = new StateModel({
        selID: 1
    });
    window.stateModel = stateModel;
    var collection = [
        { id: 1, name: 'yoyo' },
        { id: 2, name: 'wln' },
        { id: 3, name: 'pp' }
    ];
    $(function () {
        var titleView = new TitleView({
            model: stateModel,
            collection: collection
        });
        var stateView = new StateView({
            model: stateModel,
            collection: collection
        });
        //apply -----------
        stateView.render();
        $('body').append(titleView.render().el);
    });
})(jQuery);
View Code

6. 支持快捷键

(function () {
    //依赖 mousetrap.js 和 backbone.mousetrap.js
    //https://github.com/ccampbell/mousetrap and https://github.com/elasticsales/backbone.mousetrap

    //define --------------------------------
    var UserView = Backbone.View.extend({
        el: 'body',
        render: function () {
            $(this.el).html("<p>" + this.model.get('name') + "</p>");
            return this;
        },
        keyboardEvents: {
            'shift+enter': 'goBack'
        },
        goBack: function () {
            alert('shift+enter');
        }
    });
    $(function () {
        //instance ---------------------------
        var userModel = new Backbone.Model({
            name: 'ABC'
        });
        var userView = new UserView({
            model: userModel
        });
        //apply ------------------------
        userView.render();
    });
})(jQuery);
View Code

7. 路由事件

(function ($) {
    var Workspace = Backbone.Router.extend({
        routes: {
            '': 'userPage',
            'user': 'userPage',
            'users': 'userList'
        },
        initialize: function () {
            //侦听 route 事件
            Backbone.history.on('route', this.routeTracker);
            //侦听特定事件
            this.on('route:userPage', this.userPageEntent);
        },
        routeTracker: function (router, route, params) {

        },
        userPageEntent: function (param1, param2) {

        }
    });
})(jQuery);
View Code
posted on 2014-08-08 16:55  MSchina 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/yoyoone23/p/3899753.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值