Permalink
Browse files

Merge bindModel / bindCollection into bindDataObject

Merge unbindModel / unbindCollection into unbindDataObject
Remove _setModelOptions / _setCollectionOptions
  • Loading branch information...
1 parent 92b7e4d commit 34ca9a9861e78fb9121cba80809ab35c49924dea Ryan Eastridge committed Dec 26, 2012
Showing with 127 additions and 144 deletions.
  1. +9 −13 src/collection.js
  2. +84 −68 src/data-object.js
  3. +1 −5 src/event.js
  4. +9 −10 src/form.js
  5. +6 −9 src/loading.js
  6. +8 −15 src/model.js
  7. +1 −1 src/thorax.js
  8. +1 −16 src/util.js
  9. +3 −2 test/src/collection.js
  10. +3 −3 test/src/event.js
  11. +2 −2 test/src/loading.js
View
@@ -38,20 +38,15 @@ Thorax.Collections = {};
createRegistryWrapper(Thorax.Collection, Thorax.Collections);
dataObject('collection', {
- name: '_collectionEvents',
- array: '_collections',
set: 'setCollection',
setCallback: afterSetCollection,
- bind: 'bindCollection',
- unbind: 'unbindCollection',
- options: '_setCollectionOptions',
defaultOptions: {
render: true,
fetch: true,
success: false,
errors: true
},
- change: '_onCollectionReset',
+ change: onCollectionReset,
$el: 'getCollectionElement',
cidAttrName: collectionCidAttributeName
});
@@ -193,15 +188,10 @@ _.extend(Thorax.View.prototype, {
var element = this.$(this._collectionSelector);
return element.length === 0 ? this.$el : element;
},
- _onCollectionReset: function(collection) {
- if (collection === this.collection && this._objectOptionsByCid[this.collection.cid].render) {
- this.renderCollection();
- }
- },
// Events that will only be bound to "this.collection"
_collectionRenderingEvents: {
- reset: '_onCollectionReset',
- sort: '_onCollectionReset',
+ reset: onCollectionReset,
+ sort: onCollectionReset,
filter: function() {
applyVisibilityFilter.call(this);
},
@@ -245,6 +235,12 @@ Thorax.View.on({
}
});
+function onCollectionReset(collection) {
+ if (collection === this.collection && this._objectOptionsByCid[this.collection.cid].render) {
+ this.renderCollection();
+ }
+}
+
function afterSetCollection(collection) {
if (!collectionHelperPresentForPrimaryCollection.call(this) && collection) {
_.each(this._collectionRenderingEvents, function(callback, eventName) {
View
@@ -1,6 +1,10 @@
/*global getValue, inheritVars, walkInheritTree */
+
function dataObject(type, spec) {
- spec = inheritVars[type] = _.defaults({event: true}, spec);
+ spec = inheritVars[type] = _.defaults({
+ name: '_' + type + 'Events',
+ event: true
+ }, spec);
// Add a callback in the view constructor
spec.ctor = function() {
@@ -13,105 +17,117 @@ function dataObject(type, spec) {
}
};
- function bindEvents(target, source) {
- var context = this;
- walkInheritTree(source, spec.name, true, function(event) {
- // getEventCallback will resolve if it is a string or a method
- // and return a method
- context.listenTo(target, event[0], _.bind(getEventCallback(event[1], context), event[2] || context));
- });
- }
+ function setObject(dataObject, options) {
+ var old = this[type],
+ $el = getValue(this, spec.$el);
+
+ if (dataObject === old) {
+ return this;
+ }
+ if (old) {
+ this.unbindDataObject(old);
+ }
+
+ if (dataObject) {
+ this[type] = dataObject;
+
+ if (spec.loading) {
+ spec.loading.call(this);
+ }
- function loadObject(dataObject, options) {
- if (dataObject.load) {
- dataObject.load(function() {
- options && options.success && options.success(dataObject);
- }, options);
+ this.bindDataObject(dataObject, _.extend({}, this.options, options));
+ $el.attr(spec.cidAttrName, dataObject.cid);
+ dataObject.trigger('set', dataObject, old);
} else {
- dataObject.fetch(options);
+ this[type] = false;
+ if (spec.change) {
+ spec.change.call(this, false);
+ }
+ $el.removeAttr(spec.cidAttrName);
}
+ spec.setCallback && spec.setCallback.call(this, dataObject, options);
+ return this;
}
- function bindObject(dataObject, options) {
- if (this[spec.array].indexOf(dataObject) !== -1) {
+ Thorax.View.prototype[spec.set] = setObject;
+}
+
+_.extend(Thorax.View.prototype, {
+ bindDataObject: function(dataObject, options) {
+ var type = getDataObjectType(dataObject);
+ if (this._boundDataObjects.indexOf(dataObject) !== -1) {
return false;
}
// Collections do not have a cid attribute by default
ensureDataObjectCid(type, dataObject);
- this[spec.array].push(dataObject);
+ this._boundDataObjects.push(dataObject);
- var options = this[spec.options](dataObject, options);
+ var options = this._modifyDataObjectOptions(dataObject, _.extend({}, inheritVars[type].defaultOptions, options));
+ this._objectOptionsByCid[dataObject.cid] = options;
- bindEvents.call(this, dataObject, this.constructor);
- bindEvents.call(this, dataObject, this);
+ bindEvents.call(this, type, dataObject, this.constructor);
+ bindEvents.call(this, type, dataObject, this);
if (Thorax.Util.shouldFetch(dataObject, options)) {
loadObject(dataObject, options);
- } else {
+ } else if (inheritVars[type].change) {
// want to trigger built in rendering without triggering event on model
- this[spec.change](dataObject, options);
+ inheritVars[type].change.call(this, dataObject, options);
}
return true;
- }
+ },
- function unbindObject(dataObject) {
- if (this[spec.array].indexOf(dataObject) === -1) {
+ unbindDataObject: function (dataObject) {
+ if (this._boundDataObjects.indexOf(dataObject) === -1) {
return false;
}
- this[spec.array] = _.without(this[spec.array], dataObject);
+ this._boundDataObjects = _.without(this._boundDataObjects, dataObject);
dataObject.trigger('freeze');
this.stopListening(dataObject);
delete this._objectOptionsByCid[dataObject.cid];
return true;
- }
+ },
- function objectOptions(dataObject, options) {
- if (!this._objectOptionsByCid[dataObject.cid]) {
- this._objectOptionsByCid[dataObject.cid] = {};
- }
- _.extend(this._objectOptionsByCid[dataObject.cid], spec.defaultOptions, options);
- return this._objectOptionsByCid[dataObject.cid];
+ _modifyDataObjectOptions: function(dataObject, options) {
+ return options;
}
+});
- function setObject(dataObject, options) {
- var old = this[type],
- $el = getValue(this, spec.$el);
+function getDataObjectType(dataObject) {
+ if (isModel(dataObject)) {
+ return 'model';
+ } else if (isCollection(dataObject)) {
+ return 'collection';
+ } else {
+ throw new Error('Unknown data object bound: ' + (typeof dataObject));
+ }
+}
- if (dataObject === old) {
- return this;
- }
- if (old) {
- this[spec.unbind](old);
- }
+function isModel(model) {
+ return model && model.attributes && model.set;
+}
- if (dataObject) {
- this[type] = dataObject;
+function isCollection(collection) {
+ return collection && collection.indexOf && collection.models;
+}
- if (spec.loading) {
- spec.loading.call(this);
- }
+function bindEvents(type, target, source) {
+ var context = this;
+ walkInheritTree(source, '_' + type + 'Events', true, function(event) {
+ // getEventCallback will resolve if it is a string or a method
+ // and return a method
+ context.listenTo(target, event[0], _.bind(getEventCallback(event[1], context), event[2] || context));
+ });
+}
- this[spec.bind](dataObject, _.extend({}, this.options, options));
- $el.attr(spec.cidAttrName, dataObject.cid);
- dataObject.trigger('set', dataObject, old);
- } else {
- this[type] = false;
- if (spec.change) {
- this[spec.change](false);
- }
- $el.removeAttr(spec.cidAttrName);
- }
- spec.setCallback && spec.setCallback.call(this, dataObject, options);
- return this;
+function loadObject(dataObject, options) {
+ if (dataObject.load) {
+ dataObject.load(function() {
+ options && options.success && options.success(dataObject);
+ }, options);
+ } else {
+ dataObject.fetch(options);
}
-
- var extend = {};
- extend[spec.bind] = bindObject;
- extend[spec.unbind] = unbindObject;
- extend[spec.set] = setObject;
- extend[spec.options] = objectOptions;
-
- _.extend(Thorax.View.prototype, extend);
}
function getEventCallback(callback, context) {
View
@@ -46,11 +46,7 @@ _.extend(Thorax.View, {
_.extend(Thorax.View.prototype, {
freeze: function(options) {
- _.each(inheritVars, function(obj) {
- if (obj.unbind) {
- _.each(this[obj.array], this[obj.unbind], this);
- }
- }, this);
+ _.each(this._boundDataObjects, this.unbindDataObject, this);
options = _.defaults(options || {}, {
dom: true,
children: true
View
@@ -1,18 +1,17 @@
-/*global extendOptions, extendViewMember */
+/*global inheritVars */
-extendOptions('_setModelOptions', function() {
- return {
- populate: true
- };
-});
+inheritVars.model.defaultOptions.populate = true;
-extendViewMember('_onModelChange', function(model) {
+var oldModelChange = inheritVars.model.change;
+inheritVars.model.change = function() {
+ oldModelChange.apply(this, arguments);
// TODO : What can we do to remove this duplication?
- var modelOptions = model && this._objectOptionsByCid[model.cid];
+ var modelOptions = this.model && this._objectOptionsByCid[this.model.cid];
if (modelOptions && modelOptions.populate) {
- this.populate(model.attributes, modelOptions.populate === true ? {} : modelOptions.populate);
+ this.populate(this.model.attributes, modelOptions.populate === true ? {} : modelOptions.populate);
}
-});
+};
+inheritVars.model.defaultOptions.populate = true;
_.extend(Thorax.View.prototype, {
//serializes a form present in the view, returning the serialized data
View
@@ -1,4 +1,4 @@
-/*global collectionOptionNames, extendOptions, inheritVars */
+/*global collectionOptionNames, inheritVars */
var loadStart = 'load:start',
loadEnd = 'load:end',
rootObject;
@@ -333,14 +333,11 @@ if (Thorax.Router) {
}
// Propagates loading view parameters to the AJAX layer
-function loadingDataOptions() {
- return {
- ignoreErrors: this.ignoreFetchError,
- background: this.nonBlockingLoad
- };
-}
-extendOptions('_setModelOptions', loadingDataOptions);
-extendOptions('_setCollectionOptions', loadingDataOptions);
+Thorax.View.prototype._modifyDataObjectOptions = function(dataObject, options) {
+ options.ignoreErrors = this.ignoreFetchError;
+ options.background = this.nonBlockingLoad;
+ return options;
+};
inheritVars.collection.loading = function() {
var loadingView = this.loadingView,
View
@@ -24,32 +24,25 @@ Thorax.Models = {};
createRegistryWrapper(Thorax.Model, Thorax.Models);
dataObject('model', {
- name: '_modelEvents',
- array: '_models',
set: 'setModel',
- bind: 'bindModel',
- unbind: 'unbindModel',
- options: '_setModelOptions',
defaultOptions: {
render: true,
fetch: true,
success: false,
errors: true
},
- change: '_onModelChange',
+ change: onModelChange,
$el: '$el',
cidAttrName: modelCidAttributeName
});
-_.extend(Thorax.View.prototype, {
- _onModelChange: function(model) {
- var modelOptions = model && this._objectOptionsByCid[model.cid];
- // !modelOptions will be true when setModel(false) is called
- if (!modelOptions || (modelOptions && modelOptions.render)) {
- this.render();
- }
+function onModelChange(model) {
+ var modelOptions = model && this._objectOptionsByCid[model.cid];
+ // !modelOptions will be true when setModel(false) is called
+ if (!modelOptions || (modelOptions && modelOptions.render)) {
+ this.render();
}
-});
+}
Thorax.View.on({
model: {
@@ -59,7 +52,7 @@ Thorax.View.on({
}
},
change: function(model) {
- this._onModelChange(model);
+ onModelChange.call(this, model);
}
}
});
View
@@ -46,11 +46,11 @@ Thorax.View = Backbone.View.extend({
var self = this;
this._objectOptionsByCid = {};
+ this._boundDataObjects = [];
// Setup object event tracking
_.each(inheritVars, function(obj) {
self[obj.name] = [];
- if (obj.array) { self[obj.array] = []; }
});
viewsIndexedByCid[this.cid] = this;
Oops, something went wrong.

0 comments on commit 34ca9a9

Please sign in to comment.