model-list-debug.js revision 307532b5488ffbd7d839996ef17afbc70dc268d3
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav GlassYUI.add('model-list', function(Y) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass/**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav GlassProvides an API for managing an ordered list of Model instances.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav GlassIn addition to providing convenient `add`, `create`, `refresh`, and `remove`
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glassmethods for managing the models in the list, ModelLists are also bubble targets
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glassfor events on the model instances they contain. This means, for example, that
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glassyou can add several models to a list, and then subscribe to the `*:change` event
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glasson the list to be notified whenever any model in the list changes.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav GlassModelLists also maintain sort order efficiently as models are added and removed,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glassbased on a custom `comparator` function you may define (if no comparator is
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glassdefined, models are sorted in insertion order).
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass@submodule model-list
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass@class ModelList
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass@constructor
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass@uses ArrayList
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass@uses Base
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass**/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glassvar Lang = Y.Lang,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass YArray = Y.Array,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Fired when a model is added to the list.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Listen to the `on` phase of this event to be notified before a model is
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass added to the list. Calling `e.preventDefault()` during the `on` phase will
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass prevent the model from being added.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Listen to the `after` phase of this event to be notified after a model has
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass been added to the list.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @event add
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Model} model The model being added.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {int} index The index at which the model will be added.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @preventable _defAddFn
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass **/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass EVT_ADD = 'add',
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Fired when the list is completely refreshed via the `refresh()` method or
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass sorted via the `sort()` method.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Listen to the `on` phase of this event to be notified before the list is
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass refreshed. Calling `e.preventDefault()` during the `on` phase will prevent
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass the list from being refreshed.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Listen to the `after` phase of this event to be notified after the list has
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass been refreshed.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @event refresh
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Model[]} models Array of the list's new models after the refresh.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {String} src Source of the event. May be either `'refresh'` or
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass `'sort'`.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @preventable _defRefreshFn
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass **/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass EVT_REFRESH = 'refresh',
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Fired when a model is removed from the list.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Listen to the `on` phase of this event to be notified before a model is
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass removed from the list. Calling `e.preventDefault()` during the `on` phase
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass will prevent the model from being removed.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Listen to the `after` phase of this event to be notified after a model has
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass been removed from the list.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @event remove
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Model} model The model being removed.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {int} index The index of the model being removed.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @preventable _defRemoveFn
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass **/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass EVT_REMOVE = 'remove';
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glassfunction ModelList() {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass ModelList.superclass.constructor.apply(this, arguments);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass}
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav GlassY.ModelList = Y.extend(ModelList, Y.Base, {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // -- Public Properties ----------------------------------------------------
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass The `Model` class or subclass of the models in this list.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass This property is `null` by default, and is intended to be overridden in a
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass subclass or specified as a config property at instantiation time. It will be
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass used to create model instances automatically based on attribute hashes
307532b5488ffbd7d839996ef17afbc70dc268d3Ryan Grove passed to the `add()`, `create()`, and `refresh()` methods.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @property model
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @type Model
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @default `null`
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass **/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass model: null,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // -- Lifecycle Methods ----------------------------------------------------
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass initializer: function (config) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass config || (config = {});
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var model = this.model = config.model || this.model;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this.publish(EVT_ADD, {defaultFn: this._defAddFn});
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this.publish(EVT_REFRESH, {defaultFn: this._defRefreshFn});
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this.publish(EVT_REMOVE, {defaultFn: this._defRemoveFn});
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (model) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this.after('*:idChange', this._afterIdChange);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass } else {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Y.log('No model class specified.', 'warn', 'model-list');
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._clear();
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass destructor: function () {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass YArray.each(this._items, this._detachList, this);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // -- Public Methods -------------------------------------------------------
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Adds the specified model or array of models to this list.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @example
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // Add a single model instance.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass list.add(new Model({foo: 'bar'}));
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // Add a single model, creating a new instance automatically.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass list.add({foo: 'bar'});
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // Add multiple models, creating new instances automatically.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass list.add([
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass {foo: 'bar'},
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass {baz: 'quux'}
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass ]);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @method add
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Model|Model[]|Object|Object[]} models Models to add. May be existing
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass model instances or hashes of model attributes, in which case new model
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass instances will be created from the hashes.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Object} [options] Data to be mixed into the event facade of the
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass `add` event(s) for the added models.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Boolean} [options.silent=false] If `true`, no `add` event(s) will
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass be fired.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @return {Model|Model[]} Added model or array of added models.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass **/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass add: function (models, options) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (Lang.isArray(models)) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return YArray.map(models, function (model) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return this._add(model, options);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }, this);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass } else {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return this._add(models, options);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Define this method to provide a function that takes a model as a parameter
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass and returns a value by which that model should be sorted relative to other
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass models in this list.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass By default, no comparator is defined, meaning that models will not be sorted
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass (they'll be stored in the order they're added).
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @example
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var list = new Y.ModelList({model: Y.Model});
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass list.comparator = function (model) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return model.get('id'); // Sort models by id.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass };
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @method comparator
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Model} model Model being sorted.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @return {Number|String} Value by which the model should be sorted relative
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass to other models in this list.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass **/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // comparator is not defined by default
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Creates or updates the specified model on the server, then adds it to this
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass list if the server indicates success.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @method create
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Model|Object} model Model to create. May be an existing model
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass instance or a hash of model attributes, in which case a new model instance
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass will be created from the hash.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Object} [options] Options to be passed to the model's `sync()` and
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass `set()` methods and mixed into the `add` event when the model is added
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass to the list.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Boolean} [options.silent=false] If `true`, no `add` event(s) will
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass be fired.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {callback} [callback] Called when the sync operation finishes.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Error} callback.err If an error occurred, this parameter will
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass contain the error. If the sync operation succeeded, _err_ will be
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass falsy.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {mixed} callback.response The server's response.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @return {Model} Created model.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass **/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass create: function (model, options, callback) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var self = this;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // Allow callback as second arg.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (typeof options === 'function') {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass callback = options;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass options = {};
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (!(model instanceof Y.Model)) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass model = new this.model(model);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return model.save(options, function (err) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (!err) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass self.add(model, options);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass callback && callback.apply(null, arguments);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass });
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Returns the model with the specified _clientId_, or `null` if not found.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @method getByClientId
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {String} clientId Client id.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @return {Model} Model, or `null` if not found.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass **/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass getByClientId: function (clientId) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return this._clientIdMap[clientId] || null;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Returns the model with the specified _id_, or `null` if not found.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Note that models aren't expected to have an id until they're saved, so if
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass you're working with unsaved models, it may be safer to call
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass `getByClientId()`.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @method getById
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {String} id Model id.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @return {Model} Model, or `null` if not found.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass **/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass getById: function (id) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return this._idMap[id] || null;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Calls the named method on every model in the list. Any arguments provided
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass after _name_ will be passed on to the invoked method.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @method invoke
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {String} name Name of the method to call on each model.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {any} *args Zero or more arguments to pass to the invoked method.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @return {Array} Array of return values, indexed according to the index of
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass the model on which the method was called.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass **/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass invoke: function (name /*, *args */) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var args = [this._items, name].concat(YArray(arguments, 1, true));
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return YArray.invoke.apply(YArray, args);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Returns the model at the specified _index_.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @method item
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {int} index Index of the model to fetch.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @return {Model} The model at the specified index, or `undefined` if there
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass isn't a model there.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass **/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // item() is inherited from ArrayList.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Loads this list of models from the server.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass This method delegates to the `sync()` method to perform the actual load
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass operation, which is an asynchronous action. Specify a _callback_ function to
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass be notified of success or failure.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass If the load operation succeeds, a `refresh` event will be fired.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @method load
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Object} [options] Options to be passed to `sync()` and to
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass `refresh()` when adding the loaded models. It's up to the custom sync
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass implementation to determine what options it supports or requires, if any.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {callback} [callback] Called when the sync operation finishes.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Error} callback.err If an error occurred, this parameter will
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass contain the error. If the sync operation succeeded, _err_ will be
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass falsy.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {mixed} callback.response The server's response. This value will
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass be passed to the `parse()` method, which is expected to parse it and
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return an array of model attribute hashes.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @chainable
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass **/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass load: function (options, callback) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var self = this;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // Allow callback as only arg.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (typeof options === 'function') {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass callback = options;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass options = {};
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this.sync('read', options, function (err, response) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (!err) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass self.refresh(self.parse(response), options);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass callback && callback.apply(null, arguments);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass });
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return this;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Executes the specified function on each model in this list and returns an
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass array of the function's collected return values.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @method map
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Function} fn Function to execute on each model.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Model} fn.model Current model being iterated.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {int} fn.index Index of the current model in the list.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Model[]} fn.models Array of models being iterated.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Object} [thisObj] `this` object to use when calling _fn_.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @return {Array} Array of return values from _fn_.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass **/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass map: function (fn, thisObj) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return YArray.map(this._items, fn, thisObj);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Called to parse the _response_ when the list is loaded from the server.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass This method receives a server _response_ and is expected to return an array
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass of model attribute hashes.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass The default implementation assumes that _response_ is either an array of
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass attribute hashes or a JSON string that can be parsed into an array of
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass attribute hashes. If _response_ is a JSON string and either `Y.JSON` or the
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass native `JSON` object are available, it will be parsed automatically. If a
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass parse error occurs, an `error` event will be fired and the model will not be
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass updated.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass You may override this method to implement custom parsing logic if necessary.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @method parse
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {mixed} response Server response.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @return {Object[]} Array of model attribute hashes.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass **/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass parse: function (response) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (typeof response === 'string') {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass try {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return Y.JSON.parse(response) || [];
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass } catch (ex) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Y.error('Failed to parse JSON response.');
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return null;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return response || [];
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Completely replaces all models in the list with those specified, and fires a
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass single `refresh` event.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Use `refresh` when you want to add or remove a large number of items at once
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass without firing `add` or `remove` events for each one.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @method refresh
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Model[]|Object[]} models Models to add. May be existing model
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass instances or hashes of model attributes, in which case new model instances
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass will be created from the hashes.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Object} [options] Data to be mixed into the event facade of the
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass `refresh` event.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Boolean} [options.silent=false] If `true`, no `refresh` event will
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass be fired.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @chainable
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass **/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass refresh: function (models, options) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass options || (options = {});
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var facade = Y.merge(options, {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass src : 'refresh',
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass models: YArray.map(models, function (model) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return model instanceof Y.Model ? model :
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass new this.model(model);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }, this)
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass });
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass options.silent ? this._defRefreshFn(facade) :
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this.fire(EVT_REFRESH, facade);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return this;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Removes the specified model or array of models from this list.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @method remove
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Model|Model[]} models Models to remove.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Object} [options] Data to be mixed into the event facade of the
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass `remove` event(s) for the removed models.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Boolean} [options.silent=false] If `true`, no `remove` event(s)
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass will be fired.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @return {Model|Model[]} Removed model or array of removed models.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass **/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass remove: function (models, options) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (Lang.isArray(models)) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return YArray.map(models, function (model) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return this._remove(model, options);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }, this);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass } else {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return this._remove(models, options);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Forcibly re-sorts the list.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Usually it shouldn't be necessary to call this method since the list
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass maintains its sort order when items are added and removed, but if you change
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass the `comparator` function after items are already in the list, you'll need
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass to re-sort.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @method sort
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Object} [options] Data to be mixed into the event facade of the
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass `refresh` event.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Boolean} [options.silent=false] If `true`, no `refresh` event will
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass be fired.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @chainable
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass **/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass sort: function (options) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var comparator = this.comparator,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass models = this._items.concat(),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass facade;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (!comparator) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return this;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass options || (options = {});
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass models.sort(function (a, b) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var aValue = comparator(a),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass bValue = comparator(b);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return aValue < bValue ? -1 : (aValue > bValue ? 1 : 0);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass });
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass facade = Y.merge(options, {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass models: models,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass src : 'sort'
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass });
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass options.silent ? this._defRefreshFn(facade) :
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this.fire(EVT_REFRESH, facade);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return this;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Override this method to provide a custom persistence implementation for this
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass list. The default method just calls the callback without actually doing
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass anything.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass This method is called internally by `load()`.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @method sync
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {String} action Sync action to perform. May be one of the following:
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * `create`: Store a list of newly-created models for the first time.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * `delete`: Delete a list of existing models.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * 'read' : Load a list of existing models.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * `update`: Update a list of existing models.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Currently, model lists only make use of the `read` action, but other
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass actions may be used in future versions.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Object} [options] Sync options. It's up to the custom sync
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass implementation to determine what options it supports or requires, if any.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {callback} [callback] Called when the sync operation finishes.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Error} callback.err If an error occurred, this parameter will
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass contain the error. If the sync operation succeeded, _err_ will be
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass falsy.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {mixed} [callback.response] The server's response. This value will
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass be passed to the `parse()` method, which is expected to parse it and
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return an array of model attribute hashes.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass **/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass sync: function (/* action, options, callback */) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var callback = YArray(arguments, 0, true).pop();
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (typeof callback === 'function') {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass callback();
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Returns an array containing the models in this list.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @method toArray
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @return {Array} Array containing the models in this list.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass **/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass toArray: function () {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return this._items.concat();
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Returns an array containing attribute hashes for each model in this list,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass suitable for being passed to `Y.JSON.stringify()`.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Under the hood, this method calls `toJSON()` on each model in the list and
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass pushes the results into an array.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @method toJSON
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @return {Object[]} Array of model attribute hashes.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @see Model.toJSON()
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass **/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass toJSON: function () {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return this.map(function (model) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return model.toJSON();
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass });
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // -- Protected Methods ----------------------------------------------------
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Adds the specified _model_ if it isn't already in this list.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @method _add
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Model|Object} model Model or object to add.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Object} [options] Data to be mixed into the event facade of the
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass `add` event for the added model.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Boolean} [options.silent=false] If `true`, no `add` event will be
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass fired.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @return {Model} The added model.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @protected
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass **/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _add: function (model, options) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var facade;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass options || (options = {});
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (!(model instanceof Y.Model)) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass model = new this.model(model);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (this._clientIdMap[model.get('clientId')]) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Y.error('Model already in list.');
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass facade = Y.merge(options, {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass index: this._findIndex(model),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass model: model
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass });
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass options.silent ? this._defAddFn(facade) : this.fire(EVT_ADD, facade);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return model;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Adds this list as a bubble target for the specified model's events.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @method _attachList
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Model} model Model to attach to this list.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @protected
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass **/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _attachList: function (model) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // Attach this list and make it a bubble target for the model.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass model.lists.push(this);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass model.addTarget(this);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Clears all internal state and the internal list of models, returning this
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass list to an empty state. Automatically detaches all models in the list.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @method _clear
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @protected
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass **/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _clear: function () {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass YArray.each(this._items, this._detachList, this);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._clientIdMap = {};
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._idMap = {};
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._items = [];
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Removes this list as a bubble target for the specified model's events.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @method _detachList
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Model} model Model to detach.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @protected
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass **/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _detachList: function (model) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var index = YArray.indexOf(model.lists, this);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (index > -1) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass model.lists.splice(index, 1);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass model.removeTarget(this);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Returns the index at which the given _model_ should be inserted to maintain
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass the sort order of the list.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @method _findIndex
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Model} model The model being inserted.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @return {int} Index at which the model should be inserted.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @protected
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass **/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _findIndex: function (model) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var comparator = this.comparator,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass items = this._items,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass max = items.length - 1,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass min = 0,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass item, middle, needle;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (!comparator || !items.length) { return items.length; }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass needle = comparator(model);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // Perform an iterative binary search to determine the correct position
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // based on the return value of the `comparator` function.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass while (min < max) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass middle = (min + max) / 2;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass item = items[middle];
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (item && comparator(item) < needle) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass min = middle + 1;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass } else {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass max = middle;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return min;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Removes the specified _model_ if it's in this list.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @method _remove
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Model} model Model to remove.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Object} [options] Data to be mixed into the event facade of the
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass `remove` event for the removed model.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {Boolean} [options.silent=false] If `true`, no `remove` event will
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass be fired.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @return {Model} Removed model.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @protected
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass **/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _remove: function (model, options) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var index = this.indexOf(model),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass facade;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass options || (options = {});
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (index === -1) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Y.error('Model not in list.');
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
307532b5488ffbd7d839996ef17afbc70dc268d3Ryan Grove
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass facade = Y.merge(options, {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass index: index,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass model: model
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass });
307532b5488ffbd7d839996ef17afbc70dc268d3Ryan Grove
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass options.silent ? this._defRemoveFn(facade) :
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this.fire(EVT_REMOVE, facade);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return model;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // -- Event Handlers -------------------------------------------------------
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Updates the model maps when a model's `id` attribute changes.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @method _afterIdChange
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {EventFacade} e
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @protected
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass **/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _afterIdChange: function (e) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass e.prevVal && delete this._idMap[e.prevVal];
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass e.newVal && (this._idMap[e.newVal] = e.target);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // -- Default Event Handlers -----------------------------------------------
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Default event handler for `add` events.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @method _defAddFn
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {EventFacade} e
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @protected
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass **/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _defAddFn: function (e) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var model = e.model,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass id = model.get('id');
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._clientIdMap[model.get('clientId')] = model;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (id) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._idMap[id] = model;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._attachList(model);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._items.splice(e.index, 0, model);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Default event handler for `refresh` events.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @method _defRefreshFn
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {EventFacade} e
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @protected
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass **/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _defRefreshFn: function (e) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // When fired from the `sort` method, we don't need to clear the list or
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // add any models, since the existing models are sorted in place.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (e.src === 'sort') {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._items = e.models.concat();
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._clear();
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (e.models.length) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this.add(e.models, {silent: true});
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass /**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass Default event handler for `remove` events.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @method _defRemoveFn
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @param {EventFacade} e
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass @protected
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass **/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _defRemoveFn: function (e) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var model = e.model,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass id = model.get('id');
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._detachList(model);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass delete this._clientIdMap[model.get('clientId')];
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (id) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass delete this._idMap[id];
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._items.splice(e.index, 1);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass}, {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass NAME: 'modelList'
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass});
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav GlassY.augment(ModelList, Y.ArrayList);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass/**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav GlassReturns an array containing the values of the specified attribute from each
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glassmodel in this list.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass@method get
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass@param {String} name Attribute name or object property path.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass@return {Array} Array of attribute values.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass@see Model.get()
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass**/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass/**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav GlassReturns an array containing the HTML-escaped versions of the values of the
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glassspecified string attributes from each model in this list. The values are escaped
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glassusing `Y.Escape.html()`.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass@method getAsHTML
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass@param {String} name Attribute name or object property path.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass@return {String[]} Array of HTML-escaped attribute values.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass@see Model.getAsHTML()
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass**/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass/**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav GlassReturns an array containing the URL-encoded versions of the values of the
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glassspecified string attributes from each model in this list. The values are encoded
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glassusing the native `encodeURIComponent()` function.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass@method getAsURL
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass@param {String} name Attribute name or object property path.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass@return {String[]} Array of URL-encoded attribute values.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass@see Model.getAsURL()
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass**/
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav GlassY.ArrayList.addMethod(ModelList.prototype, [
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass 'get', 'getAsHTML', 'getAsURL'
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass]);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass}, '@VERSION@' ,{requires:['array-extras', 'array-invoke', 'arraylist', 'base-build', 'json-parse', 'model']});