首页 > 代码库 > 2014/08/05 – Backbonejs

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 = http://www.mamicode.com/modelInstance.get(‘code‘);    //设置属性值(没有则创建,可用 JSON 更新多值,更新成功返回 true )    var isUpdate = modelInstance.set(‘name‘, ‘Penny‘);    //删除属性    modelInstance.unset(‘name‘);    //清空属性    modelInstance.clear();    //获取属性是否存在    var isHas = modelInstance.has(‘code‘);    //获取 HTML 转移后的属性值    attValue = http://www.mamicode.com/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 = http://www.mamicode.com/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