首页 > 网站 > WEB开发 > 正文

backbone.Collection源码笔记

2024-04-27 14:21:11
字体:
来源:转载
供稿:网友

backbone.Collection源码笔记

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里面去
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表