2014/08/05 – Backbonejs

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

Model API:

(function ($) {

    //define Model Class -------------------
    var ModelClass = Backbone.Model.extend({
        defaults: {},//Backbone 支持在模型初始化时动态进行定义 [支持多行表达式设置默认值,即值为函数]
        initialize: function () {
            //模型对象被创建后即被调用

            /* 注:如定义了默认属性,那么会覆盖在 initialize() 函数中设置的值。 */

        },
        /* 如未初始化模型标识符,则可用客户端标识符 cid */
        idAttribute: ‘code‘,//手动设置模型标识符属性名 [默认为 id ]
        validate: function (attrs) {
            //如不合法则返回一条错误信息,触发 invalid 事件
            //call save 方法时被触发
            /* 注:如调用 set() 方法时传人 {validate:true} 作为其最后一个参数也可触发
               如: model.set(‘name‘,‘value‘,{validate:true}); */
            //验证过程中,可通过 this.get() 和 this.attributes 来访问更改前的属性值
        }
    });

    //instance -------------------------
    var modelInstance = new ModelClass({
        code: 1,
        name: ‘Jeff‘
    });

    //apply ------------------------------

    /* 所有属性都被存放在对象的 attributes 属性中。 */

    //获取模型独立的副本
    var modelCopy = modelInstance.clone();
    //获取属性值
    var attValue = modelInstance.get(‘code‘);
    //设置属性值(没有则创建,可用 JSON 更新多值,更新成功返回 true )
    var isUpdate = modelInstance.set(‘name‘, ‘Penny‘);
    //删除属性
    modelInstance.unset(‘name‘);
    //清空属性
    modelInstance.clear();
    //获取属性是否存在
    var isHas = modelInstance.has(‘code‘);
    //获取 HTML 转移后的属性值
    attValue = modelInstance.escape(‘name‘);
    //验证错误事件绑定
    modelInstance.on(‘invalid‘, function (model, error) {

    });
    //或作为参数传入 set, fetch, save ,destroy 方法
    modelInstance.set(‘name‘, ‘value‘, {
        invalid: function (model, error) {

        },
        validate: true
    });
    //手动触发验证,成功返回 true [不触发 invalid 事件]
    var isValidate = modelInstance.isValid();

})(jQuery);

插件扩展:

1. 重写 setter 和 getter

(function ($) {

    //依赖 backbone.mutators.js
    //https://github.com/asciidisco/Backbone.Mutators

    /* 注:如果使用 setter 方法为属性赋值,那么触发它的唯一方式就是调用 set() 方法。
        在初始化模型时,除非为属性显示触发 change 事件,否则其 setter 赋值方法不会被调用,原因是change不会被触发。*/

    //define ----------------------------
    var ModelM = Backbone.Model.extend({
        mutators: {
            //重写虚属性
            fullName: {
                get: function () {
                    return this.firstName + ‘ ‘ + this.lastName;
                },
                set: function (key, value, options, set) {
                    var names = value.split(‘ ‘);
                    this.set(‘firstName‘, names[0], options);
                    this.set(‘lastName‘, names[0], options);
                }
            },
            //重写已有属性
            isAdmin: {
                get: function () {
                    return this.isAdmin ? "Admin" : "Guest";
                    /* 注:可通过模型对象的 attributes 属性来获得其属性的原始值
                       如: modelInstance.attributes.isAdmin */
                },
                set: function (key, value, options, set) {
                    set(key, value === "Admin", options);
                }
            }
        }
    });
    //instance --------------------------
    var modelInstance = new ModelM({
        firstName: ‘James‘,
        lastName: ‘Bell‘,
        isAdmin: true
    });
    //apply ----------------------
    modelInstance.get(‘fullName‘);
    modelInstance.set(‘fullName‘, ‘Yo ABC‘);
    //绑定赋值方法事件
    modelInstance.on(‘mutators:set:fullName‘, function (a, b, c, d) {

    });

})(jQuery);
View Code

2. 保存和恢复模型状态

(function ($) {
    //依赖 backbone.memento.js
    //https://github.com/derickbailey/backbone.memento

    //define ---------------------------
    var ModelT = Backbone.Model.extend({
        initialize: function () {
            //插件扩展
            _.extend(this, new Backbone.Memento(this, {
                ignore: [‘description‘]//被忽略的属性集合
            }));
        }
    });

    //instance -----------------
    var modelInstance = new ModelT({
        name: ‘James‘,
        description: ‘‘,
        age: 22
    });

    //apply --------------------
    modelInstance.set(‘age‘, 23);
    //保存状态
    modelInstance.store();

    modelInstance.set(‘age‘, 25);
    var ageValue = modelInstance.get(‘age‘);

    //获取之前状态
    modelInstance.restore();
    ageValue = modelInstance.get(‘age‘);

    //恢复到第一个状态
    modelInstance.restart();
    ageValue = modelInstance.get(‘age‘);

})(jQuery);
View Code

3. 工作流

(function ($) {
    //依赖 backbone.workflow.js
    //https://github.com/kendagriff/workflow.js

    //define ---------------------------
    var ModelW = Backbone.Model.extend({
        workflow: {
            initial: ‘draft‘,//默认状态
            //定义工作流转换状态集合
            events: [
                { name: ‘issue‘, from: ‘draft‘, to: ‘issued‘ },
                { name: ‘payout‘, from: ‘issued‘, to: ‘paid‘ },
                { name: ‘cancel‘, from: ‘draft‘, to: ‘canceled‘ },
                { name: ‘cancel‘, from: ‘issued‘, to: ‘canceled‘ }
            ]
        },
        initialize: function () {
            //扩展插件
            _.extend(this, new Backbone.Workflow(this, { attrName: ‘status‘ }));//设置状态属性名

            //绑定工作流相应转换事件
            this.bind(‘transition:from:draft‘, function () {
            });
            this.bind(‘transition:to:issued‘, function () {
            });
        }
    });

    //instance ------------------------
    var modelInstance = new ModelW();
    var status = modelInstance.get(‘status‘);//draft
    //工作流转换
    /* 注:只有 triggerEvent 方法才能触发转换事件 */
    modelInstance.triggerEvent(‘issue‘);
    status = modelInstance.get(‘status‘);//issued
})(jQuery);
View Code

4. 高级验证

(function ($) {
    //依赖 backbone.validation.js
    //https://github.com/thedersen/backbone.validation

    //define -----------------------------------------------------
    //插件扩展
    _.extend(Backbone.Model.prototype, Backbone.Validation.mixin);

    var ModelV = Backbone.Model.extend({
        validation: {
            name: {
                required: true,//必填
                length: 16,//字符长度
                oneOf: [‘ABCDEF‘, ‘FEDCBA‘]//唯一匹配
            },
            email: {
                pattern: ‘email‘,//类型(number, digits, email, url)和正则
                minLength: 10,//字符最小长度
                maxLength: 20,//字符最大长度
                rangeLenght: [10, 20]//字符区间
            },
            twoEmail: {
                equalTo: ‘email‘//和另一个属性相同
            },
            isAccept: {
                acceptance: true// boolean 校验
            },
            age: {
                min: 18,//数字最小
                max: 60,//数字最大
                range: [18, 60]//数字区间
            }
        }
    });

    //用法同基础校验相同

    /* 验证 HTML 表单 */
    //在 View Model 的 initialize 函数里 扩展插件 Backbone.Validation.bind(this);
    //生成的 HTML 会带有 class=‘invalid‘ data-error=‘‘
})(jQuery);
View Code

5. 复杂嵌套属性

(function ($) {
    //依赖 backbone.nested.js
    //https://github.com/afeld/backbone-nested

    //define --------------------------
    //使用其基类进行扩展
    var ModelN = Backbone.NestedModel.extend({});

    //instance -------------------------
    var modelInstance = new ModelN();

    //apply -------------------
    modelInstance.set({
        ‘name.title‘: ‘Mr‘,
        ‘name.generation‘: ‘II‘
    });
    modelInstance.get(‘name‘); //{title:‘Mr‘,generation:‘II‘}
    modelInstance.get(‘name.title‘); //Mr

    //值为数组
    modelInstance.set({
        ‘addresses‘: [
            { city: ‘Brooklyn‘, state: ‘NY‘ },
            { city: ‘Oak Park‘, state: ‘IL‘ }
        ]
    });
    modelInstance.set(‘addresses[1].state‘, ‘MI‘);
    modelInstance.get(‘addresses[1].state‘);//MI
    //add remove
    modelInstance.add(‘addresses‘, { city: ‘TianJin‘, state: ‘TJ‘ });
    modelInstance.remove(‘addresses[2]‘);
    //bind 回调事件
    modelInstance.bind(‘change:addresses[0].city‘, function (model, value) {

    });
})(jQuery);
View Code

6. 模型对象间一对一关联关系

(function ($) {
    //依赖 backbone.relational.js
    //https://github.com/pauluithol/backbone-relational

    //define ----------------------------------------
    //通过其基类进行扩展
    var UserModel = Backbone.RelationalModel.extend({});

    var BuyerModel = Backbone.RelationalModel.extend({
        relations: [
            {
                type: Backbone.HasOne,//一对一枚举值
                key: ‘user‘,//相关模型属性名称
                relatedModel: UserModel,//相关模型对象
                reverseRelation: {//反向关联设置
                    type: Backbone.HasOne,
                    key: ‘buyer‘
                }
            }
        ]
    });

    //instance ------------------------------------
    var userInstance = new UserModel({
        name: ‘James‘
    });
    var buyerInstance = new BuyerModel({
        fullName: ‘James Bell‘,
        user: userInstance
    });
    buyerInstance.get(‘user‘).get(‘name‘);//James

    var user2 = new UserModel({
        name: ‘Bell‘,
        buyer: {//快捷定义
            fullName: ‘James Bell‘
        }
    });
    user2.get(‘buyer‘).get(‘fullName‘);//James Bell

})(jQuery);
View Code

2014/08/05 – Backbonejs,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。