backbone.Model
backbone的model(模型),用来存储数据,交互数据,数据验证,在view里面可以直接监听model来达到model一改变,就通知视图.
这个里面的代码是从backbone里面剥离出来,然后一点一点研究和调试出来的,可以单独运行,依赖underscore,jquery或者是zepto event.js是剥离出来的Backbone.Events
<!DOCTYPE html><html><head> <meta charset="utf-8"/> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" /> <title>backbone</title> <style type="text/CSS"> *{padding:0;margin:0;} .wrap{width:960px; margin: 100px auto; padding: 20px 0;} ul{ list-style: none;} </style></head><body> <div class="wrap"> <div id="a1"></div> <div id="a2"></div> <div id="a3"></div> </div><script src="http://files.cnblogs.com/wtcsy/jquery.js"></script> <script src="http://files.cnblogs.com/wtcsy/underscore.js"></script><script src="http://files.cnblogs.com/wtcsy/events.js"></script><script>(function(){ // Backbone.Model // -------------- // Backbone **Models** are the basic data object in the framework -- // frequently rePResenting a row in a table in a database on your server. // A discrete chunk of data and a bunch of useful, related methods for // performing computations and transformations on that data. // Create a new model with the specified attributes. A client id (`cid`) // is automatically generated and assigned for you. var Model = Backbone.Model = function(attributes, options) { var attrs = attributes || {}; options || (options = {}); //每个molde都有一个cid 唯一的标识 this.cid = _.uniqueId('c'); //这个是存放设置值得hash列表 this.attributes = {}; //看这个model是属于哪个collection if (options.collection) this.collection = options.collection; //格式化参数 默认是不做变化的,可以自己扩展parse方法实现 if (options.parse) attrs = this.parse(attrs, options) || {}; attrs = _.defaults({}, attrs, _.result(this, 'defaults')); this.set(attrs, options); // 被改变了的值 this.changed = {}; this.initialize.apply(this, arguments); }; _.extend(Model.prototype, Backbone.Events, { // A hash of attributes whose current and previous value differ. //存放 与之前attributes里面改变了的值 changed: null, //验证失败后返回的信息 // The value returned during the last failed validation. validationError: null, // The default name for the JSON `id` attribute is `"id"`. MongoDB and // CouchDB users may want to set this to `"_id"`. idAttribute: 'id', // The function that will generate an id for a model given that model's // attributes. generateId: function (attrs) { return attrs[this.idAttribute]; }, // Initialize is an empty function by default. Override it with your own // initialization logic. // 实例化一个model的时候总会被调用的方法 initialize: function(){}, // Return a copy of the model's `attributes` object. // 复制model.的attributes的属性 toJSON: function(options) { return _.clone(this.attributes); }, // Proxy `Backbone.sync` by default -- but override this if you need // custom syncing semantics for *this* particular model. sync: function() { return Backbone.sync.apply(this, arguments); }, // Get the value of an attribute. get: function(attr) { return this.attributes[attr]; }, // Get the HTML-escaped value of an attribute. escape: function(attr) { return _.escape(this.get(attr)); }, // Remove an attribute from the model, firing `"change"`. `unset` is a noop // if the attribute doesn't exist. // 删除model上的数据 触发监听 change 和 unset的回调 unset: function(attr, options) { return this.set(attr, void 0, _.extend({}, options, {unset: true})); }, // Clear all attributes on the model, firing `"change"`. clear: function(options) { var attrs = {}; for (var key in this.attributes) attrs[key] = void 0; return this.set(attrs, _.extend({}, options, {unset: true})); }, // Determine if the model has changed since the last `"change"` event. // If you specify an attribute name, determine if that attribute has changed. // 查看某个是属性值 是否被修改了 hasChanged: function(attr) { if (attr == null) return !_.isEmpty(this.changed); return _.has(this.changed, attr); }, // Return an object containing all the attributes that have changed, or // false if there are no changed attributes. Useful for determining what // parts of a view need to be updated and/or what attributes need to be // persisted to the server. Unset attributes will be set to undefined. // You can also pass an attributes object to diff against the model, // determining if there *would be* a change. changedAttributes: function(diff) { if (!diff) return this.hasChanged() ? _.clone(this.changed) : false; var val, changed = false; var old = this._changing ? this._previousAttributes : this.attributes; for (var attr in diff) { if (_.isEqual(old[attr], (val = diff[attr]))) continue; (changed || (changed = {}))[attr] = val; } return changed; }, // Get the previous value of an attribute, recorded at the time the last // `"change"` event was fired. //取改变了attribute之前的某个属性值 previous: function(attr) { if (attr == null || !this._previousAttributes) return null; return this._previousAttributes[attr]; }, // Get all of the attributes of the model at the time of the previous // `"change"` event. //获取改变了attribute之前 previousAttributes: function() { return _.clone(this._previousAttributes); }, // Set a hash of model attributes on the object, firing `"change"`. This is // the core primitive Operation of a model, updating the data and notifying // anyone who needs to know about the change in state. The heart of the beast. set: function(key, val, options) { var attr, attrs, unset, changes, silent, changing, prev, current; if (key == null) return this; // Handle both `"key", value` and `{key: value}` -style arguments. // 根据传参的不同 统一成key : value的形式 if (typeof key === 'object') { attrs = key; options = val; } else { (attrs = {})[key] = val; } options || (options = {}); // Run validation. // 如果需要验证数据格式, 进行验证, 验证不通过 则返回 if (!this._validate(attrs, options)) return false; // Extract attributes and options. // unset表示删除 // changes 是存放改变值得数组 // changing 属性值是否正在改变中 unset = options.unset; silent = options.silent; changes = []; changing = this._changing; this._changing = true; //如果不是在改变值得进行中 复制this.attributes 到 this._previousAttributes if (!changing) { this._previousAttributes = _.clone(this.attributes); this.changed = {}; } current = this.attributes, prev = this._previousAttributes; // For each `set` attribute, update or delete the current value. for (attr in attrs) { val = attrs[attr]; // 如果设置的属性的值,和当前的值不
新闻热点
疑难解答