Backbone.Collection
backbone的Collection(集合),用来存储多个model,并且可以多这些model进行数组一样的操作,比如添加,修改,删除,排序,插入,根据索引取值,等等,数组有的方法,他基本上都有
源码注释
<!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 src="http://files.cnblogs.com/wtcsy/model.js"></script><script>(function(){ // Backbone.Collection // ------------------- var array = []; var slice = array.slice; // If models tend to rePResent a single row of data, a Backbone Collection is // more analogous to a table full of data ... or a small slice or page of that // table, or a collection of rows that belong together for a particular reason // -- all of the messages in this particular folder, all of the documents // belonging to this particular author, and so on. Collections maintain // indexes of their models, both in order, and for lookup by `id`. // Create a new **Collection**, perhaps to contain a specific type of `model`. // If a `comparator` is specified, the Collection will maintain // its models in sort order, as they're added and removed. var Collection = Backbone.Collection = function(models, options) { options || (options = {}); //默认的model if (options.model) this.model = options.model; if (options.comparator !== void 0) this.comparator = options.comparator; //重置collection里面的的一些属性 this._reset(); this.initialize.apply(this, arguments); //如果传入的models有数据,可以进行设置 if (models) this.reset(models, _.extend({silent: true}, options)); }; // Default options for `Collection#set`. // 设置的参数 添加的参数 add var setOptions = {add: true, remove: true, merge: true}; var addOptions = {add: true, remove: false}; _.extend(Collection.prototype, Backbone.Events, { // The default model for a collection is just a **Backbone.Model**. // This should be overridden in most cases. model: Backbone.Model, // Initialize is an empty function by default. Override it with your own // initialization logic. initialize: function(){}, // The JSON representation of a Collection is an array of the // models' attributes. toJSON: function(options) { return this.map(function(model){ return model.toJSON(options); }); }, // Proxy `Backbone.sync` by default. /* sync: function() { return Backbone.sync.apply(this, arguments); }, */ // **parse** converts a response into a list of models to be added to the // collection. The default implementation is just to pass it through. parse: function(resp, options) { return resp; }, // Add a model, or list of models to the set. add: function(models, options) { //其实就是调用set方法 只有add设置成true remove设置成false merge设置成false return this.set(models, _.extend({merge: false}, options, addOptions)); }, // Update a collection by `set`-ing a new list of models, adding new ones, // removing models that are no longer present, and merging models that // already exist in the collection, as necessary. Similar to **Model#set**, // the core Operation for updating the data contained by the collection. set: function(models, options) { options = _.defaults({}, options, setOptions); //parse 必须是一个函数 传入的后将models进行一次转换 if (options.parse) models = this.parse(models, options); var singular = !_.isArray(models); models = singular ? (models ? [models] : []) : models.slice(); var id, model, attrs, existing, sort; var at = options.at; // this.comparator 是排序的东西 如果是函数 sotrAttr为null 否则sotrAttr为true var sortable = this.comparator && (at == null) && options.sort !== false; var sortAttr = _.isString(this.comparator) ? this.comparator : null; var toAdd = [], toRemove = [], modelMap = {}; var add = options.add, merge = options.merge, remove = options.remove; var order = !sortable && add && remove ? [] : false; var targetProto = this.model.prototype; // Turn bare objects into model references, and prevent invalid models // from being added. //对models进行一次遍历 找出要add的 要remove的 for (var i = 0, length = models.length; i < length; i++) { attrs = models[i] || {}; //通过查找model的属性找出id 可以是方便后面用 id可以是model本身 也可以是model的cid 或者是model的id if (this._isModel(attrs)) { id = model = attrs; } else if (targetProto.generateId) { id = targetProto.generateId(attrs); } else { id = attrs[targetProto.idAttribute || Model.prototype.idAttribute]; } // If a duplicate is found, prevent it from being added and // optionally merge it into the existing model. // return this._byId[obj] || this._byId[obj.id] || this._byId[obj.cid]; // 看model是否在this.models里面存在 如果存在,并且设置了remove吧model放到modelMap中 // 如果设置了merge model重新设置他的属性 如果设置了排序 排序标识sotr设置成true,数据改变了 肯定要排序一次的 if (existing = this.get(id)) { if (remove) modelMap[existing.cid] = true; if (merge) { attrs = attrs === model ? model.attributes : attrs; if (options.parse) attrs = existing.parse(attrs, options); existing.set(attrs, options); if (sortable && !sort && existing.hasChanged(sortAttr)) sort = true; } models[i] = existing; // If this is a new, valid model, push it to the `toAdd` list. } else if (add) { // 如果遍历的model不存在 变并且设置了add //对这个model做一些操作_prepareModel 如果传入的attrs是backbone实例化的model则只设置model.collection指向this //如果attrs只是数据 则实例化model并且model.collection指向this // 然后把model放到 toAdd中 方便后面使用 //最后 以model的cid为key 存入this._byId中 model = models[i] = this._prepareModel(attrs, options); if (!model) continue; toAdd.push(model); this._addReference(model, options); } // Do not add multiple models with the same `id`. model = existing || model; if (!model) continue; //order 如果是add或者是remove并且没有设置排序 并且model是新实例化的 添加到order里面去 后面会用到 if (order && (model.isNew() || !modelMap[model.id])) order.push(model); modelMap[model.id] = true; } // Remove nonexistent models if appropriate. if (remove) { // 做删除 先做一些准备 然后添加到toRemove里面去
新闻热点
疑难解答