Created
May 30, 2012 22:44
-
-
Save rgrove/2839394 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var AttrProto = Y.Attribute.prototype, | |
GlobalEnv = YUI.namespace('Env.Model'), | |
Lang = Y.Lang, | |
YArray = Y.Array, | |
EVT_ADD = 'add', | |
EVT_ERROR = 'error', | |
EVT_RESET = 'reset'; | |
Y.LazyModelList = Y.Base.create('lazyModelList', Y.ModelList, [], { | |
// -- Public Methods ------------------------------------------------------- | |
get: function (name) { | |
if (this.attrAdded(name)) { | |
return AttrProto.get.apply(this, arguments); | |
} | |
return YArray.map(this._items, function (item) { | |
return item[name]; | |
}); | |
}, | |
getAsHTML: function (name) { | |
if (this.attrAdded(name)) { | |
return Y.Escape.html(AttrProto.get.apply(this, arguments)); | |
} | |
return YArray.map(this._items, function (item) { | |
return Y.Escape.html(item[name]); | |
}); | |
}, | |
getAsURL: function (name) { | |
if (this.attrAdded(name)) { | |
return encodeURIComponent(AttrProto.get.apply(this, arguments)); | |
} | |
return YArray.map(this._items, function (item) { | |
return encodeURIComponent(item[name]); | |
}); | |
}, | |
indexOf: function (model) { | |
return YArray.indexOf(model._isYUIModel ? | |
this._models : this._items, model); | |
}, | |
reset: function (models, options) { | |
models || (models = []); | |
options || (options = {}); | |
var facade = Y.merge({src: 'reset'}, options); | |
if (models._isYUIModelList) { | |
models = models.toArray(); // assume we'll get an array of plain objects (for now) | |
} | |
facade.models = models; | |
if (options.silent) { | |
this._defResetFn(facade); | |
} else { | |
// Sort the models before firing the reset event. | |
if (this.comparator) { | |
models.sort(Y.bind(this._sort, this)); | |
} | |
this.fire(EVT_RESET, facade); | |
} | |
return this; | |
}, | |
toJSON: function () { | |
return this.toArray(); | |
}, | |
revive: function (item) { | |
return Lang.isNumber(item) ? | |
this._reviveIndex(item) : this._reviveObject(item); | |
}, | |
// -- Protected Methods ---------------------------------------------------- | |
// Generates ad-hoc clientIds for non-instantiated models. | |
_generateClientId: function () { | |
GlobalEnv.lastId || (GlobalEnv.lastId = 0); | |
return this.model.NAME + '_' + (GlobalEnv.lastId += 1); | |
}, | |
_reviveIndex: function (index) { | |
return this._models[index] || this._reviveObject(this._items[index], index); | |
}, | |
_reviveObject: function (model, index) { | |
if (!model) { | |
return null; | |
} | |
if (!model._isYUIModel) { | |
model = new this.model(model); | |
this._attachList(model); | |
} | |
if (index || index === 0) { | |
this._models[index] = model; | |
} | |
return model; | |
}, | |
_isInList: function (item) { | |
return ('clientId' in item && this._clientIdMap[item.clientId]) || | |
('id' in item && this._idMap[item.id]); | |
}, | |
_add: function (item, options) { | |
var facade; | |
options || (options = {}); | |
// Ensure that the item has a clientId. | |
'clientId' in item || (item.clientId = this._generateClientId()); | |
if (this._isInList(item)) { | |
this.fire(EVT_ERROR, { | |
error: 'Model is already in the list.', | |
model: item, | |
src : 'add' | |
}); | |
return; | |
} | |
facade = Y.merge(options, { | |
index: 'index' in options ? options.index : this._findIndex(item), | |
model: item | |
}); | |
options.silent ? this._defAddFn(facade) : this.fire(EVT_ADD, facade); | |
return item; | |
}, | |
_clear: function () { | |
YArray.each(this._models, this._detachList, this); | |
this._clientIdMap = {}; | |
this._idMap = {}; | |
this._items = []; | |
this._models = []; | |
}, | |
_remove: function (item, options) { | |
// If the given item is a model instance, turn it into an index before | |
// calling the parent _remove method, since we only want to deal with | |
// the plain object version. | |
if (item._isYUIModel) { | |
item = this.indexOf(item); | |
} | |
return Y.ModelList.prototype._remove.call(this, item, options); | |
}, | |
// -- Default Event Handlers ----------------------------------------------- | |
_defAddFn: function (e) { | |
var item = e.model; | |
this._clientIdMap[item.clientId] = item; | |
if (Lang.isValue(item.id)) { | |
this._idMap[item.id] = item; | |
} | |
this._items.splice(e.index, 0, item); | |
}, | |
_defRemoveFn: function (e) { | |
var index = e.index, | |
item = e.model, | |
model = this._models[index]; | |
delete this._clientIdMap[item.clientId]; | |
if ('id' in item) { | |
delete this._idMap[item.id]; | |
} | |
if (model) { | |
this._detachList(model); | |
this._models.splice(index, 1); | |
} | |
this._items.splice(index, 1); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment