Skip to content

Commit

Permalink
see readme for v1.0.6
Browse files Browse the repository at this point in the history
  • Loading branch information
rhysbrettbowen committed Nov 27, 2012
1 parent d7a6a2a commit 0b0bb0e
Show file tree
Hide file tree
Showing 9 changed files with 253 additions and 43 deletions.
68 changes: 41 additions & 27 deletions collection.js
Expand Up @@ -8,6 +8,8 @@ goog.provide('mvc.Collection');
goog.require('goog.events.Event'); goog.require('goog.events.Event');
goog.require('goog.events.EventTarget'); goog.require('goog.events.EventTarget');
goog.require('mvc.Model'); goog.require('mvc.Model');
goog.require('mvc.Mod');
goog.require('mvc.Filter');






Expand Down Expand Up @@ -37,12 +39,8 @@ mvc.Collection = function(opt_options) {
*/ */
this.models_ = []; this.models_ = [];


/** this.comparator_ = [defaults['comparator'] &&
* @private goog.bind(defaults['comparator'], this)];
* @type {?function(mvc.Model, mvc.Model):number}
*/
this.comparator_ = defaults['comparator'] &&
goog.bind(defaults['comparator'], this);


/** /**
* @private * @private
Expand Down Expand Up @@ -85,11 +83,9 @@ mvc.Collection = function(opt_options) {
this.removedModelsFns_ = []; this.removedModelsFns_ = [];




/** this.modelChange_ = [false];
* @private
* @type {boolean} this.anyModelChange_ = [false];
*/
this.modelChange_ = false;


/** /**
* @private * @private
Expand Down Expand Up @@ -146,11 +142,29 @@ mvc.Collection.prototype.pluck = function(key) {
* @param {boolean=} opt_silent to suppress change event. * @param {boolean=} opt_silent to suppress change event.
*/ */
mvc.Collection.prototype.setComparator = function(fn, opt_silent) { mvc.Collection.prototype.setComparator = function(fn, opt_silent) {
this.comparator_ = goog.bind(fn, this); this.comparator_[0] = goog.bind(fn, this);
this.sort(opt_silent); this.sort(opt_silent);
}; };





mvc.Collection.prototype.getFiltered = function(fn) {
/** @constructor */
var Filter = function() {};

Filter.prototype = this;
var filter = new Filter();
filter.init = function(a,b) {};

goog.mixin(filter, mvc.Mod);
goog.mixin(filter, mvc.Filter);

filter.init(this, fn);

return filter;
};


/** /**
* returns the number of models in the collection * returns the number of models in the collection
* *
Expand All @@ -168,8 +182,8 @@ mvc.Collection.prototype.getLength = function() {
*/ */
mvc.Collection.prototype.sort = function(opt_silent) { mvc.Collection.prototype.sort = function(opt_silent) {
var changeOrder = false; var changeOrder = false;
if (this.comparator_) { if (this.comparator_[0]) {
var comp = this.comparator_; var comp = this.comparator_[0];


// need to wrap comparator in function to record a change // need to wrap comparator in function to record a change
this.models_.sort(function(a, b) { this.models_.sort(function(a, b) {
Expand All @@ -178,7 +192,7 @@ mvc.Collection.prototype.sort = function(opt_silent) {
changeOrder = true; changeOrder = true;
return ret; return ret;
}); });
this.modelChange_ = this.modelChange_ || changeOrder; this.modelChange_[0] = this.modelChange_[0] || changeOrder;
} }
if (!opt_silent) { if (!opt_silent) {
this.dispatchEvent(goog.events.EventType.CHANGE); this.dispatchEvent(goog.events.EventType.CHANGE);
Expand Down Expand Up @@ -220,10 +234,10 @@ mvc.Collection.prototype.add = function(model, opt_ind, opt_silent) {


// insert model and setup listeners for changes // insert model and setup listeners for changes
insert = true; insert = true;
this.modelChange_ = true; this.modelChange_[0] = true;
this.anyModelChange_ = true; this.anyModelChange_[0] = true;
var changeId = mod.bindAll(goog.bind(function() { var changeId = mod.bindAll(goog.bind(function() {
this.anyModelChange_ = true; this.anyModelChange_[0] = true;
this.sort(); this.sort();
}, this)); }, this));
var unloadId = mod.bindUnload(function(e) { var unloadId = mod.bindUnload(function(e) {
Expand Down Expand Up @@ -298,8 +312,8 @@ mvc.Collection.prototype.remove = function(model, opt_silent) {
if (modelObj) { if (modelObj) {


// remove listeners and remove model // remove listeners and remove model
this.modelChange_ = true; this.modelChange_[0] = true;
this.anyModelChange_ = true; this.anyModelChange_[0] = true;
model.unbind(modelObj.unload); model.unbind(modelObj.unload);
model.unbind(modelObj.change); model.unbind(modelObj.change);
goog.array.remove(this.models_, modelObj); goog.array.remove(this.models_, modelObj);
Expand Down Expand Up @@ -408,7 +422,7 @@ mvc.Collection.prototype.clear = function(opt_silent, opt_filter) {
modelsToClear = goog.array.filter(modelsToClear, /** @type {Function} */(opt_filter)); modelsToClear = goog.array.filter(modelsToClear, /** @type {Function} */(opt_filter));
} }
this.remove(modelsToClear, true); this.remove(modelsToClear, true);
this.modelChange_ = true; this.modelChange_[0] = true;
if (!opt_silent) { if (!opt_silent) {
this.dispatchEvent(goog.events.EventType.CHANGE); this.dispatchEvent(goog.events.EventType.CHANGE);
} }
Expand Down Expand Up @@ -549,15 +563,15 @@ mvc.Collection.prototype.change_ = function() {
goog.base(this, 'change_'); goog.base(this, 'change_');


// if the models have changed then fire listeners // if the models have changed then fire listeners
if (this.modelChange_) { if (this.modelChange_[0]) {
goog.array.forEach(goog.array.clone(this.modelChangeFns_), function(fn) { goog.array.forEach(goog.array.clone(this.modelChangeFns_), function(fn) {
fn(this); fn(this);
}, this); }, this);
this.modelChange_ = false; this.modelChange_[0] = false;
} }


// if the models have changed any values then fire listeners // if the models have changed any values then fire listeners
if (this.anyModelChange_) { if (this.anyModelChange_[0]) {
goog.array.forEach(goog.array.clone(this.anyModelChangeFns_), function(fn) { goog.array.forEach(goog.array.clone(this.anyModelChangeFns_), function(fn) {
fn(this); fn(this);
}, this); }, this);
Expand All @@ -577,20 +591,20 @@ mvc.Collection.prototype.change_ = function() {
} }
}, this); }, this);
} }
this.anyModelChange_ = false; this.anyModelChange_[0] = false;
} }


goog.array.forEach(this.removedModelsFns_, function(fn) { goog.array.forEach(this.removedModelsFns_, function(fn) {
goog.array.forEach(this.removedModels_, function(mod) { goog.array.forEach(this.removedModels_, function(mod) {
fn(mod.model, mod.id); fn(mod.model, mod.id);
}); });
}, this); }, this);
this.removedModels_ = []; goog.array.clear(this.removedModels_);


goog.array.forEach(this.addedModelsFns_, function(fn) { goog.array.forEach(this.addedModelsFns_, function(fn) {
goog.array.forEach(this.addedModels_, function(mod) { goog.array.forEach(this.addedModels_, function(mod) {
fn(mod); fn(mod);
}); });
}, this); }, this);
this.addedModels_ = []; goog.array.clear(this.addedModels_);
}; };
2 changes: 1 addition & 1 deletion layout.js
Expand Up @@ -329,4 +329,4 @@ mvc.Layout.prototype.removeChild = function(
/** /**
* @type {?Function} * @type {?Function}
*/ */
mvc.Layout.prototype.placeChild_ = null; mvc.Layout.prototype.placeChild_ = null;
95 changes: 95 additions & 0 deletions mod.js
@@ -0,0 +1,95 @@
goog.provide('mvc.Mod');
goog.provide('mvc.Filter');



mvc.Mod = {

/** @this {mvc.Mod} */
init_: function() {
goog.events.listen(this.collection, goog.events.EventType.CHANGE,
this.change_, false, this);
},

/** @this {mvc.Mod} */
bindUnload: function(fn, opt_handler) {
var ret = this.collection.bind(fn, opt_handler);
},

/** @this {mvc.Mod} */
bind: function(name, fn, opt_handler) {
return this.passBind_(this.collection.bind, arguments);
},

/** @this {mvc.Mod} */
bindAll: function(fn, opt_handler) {
return this.passBind_(this.collection.bindAll, arguments);
},

/** @this {mvc.Mod} */
modelChange: function(fn, opt_handler) {
return this.passBind_(this.collection.modelChange, arguments);
},

/** @this {mvc.Mod} */
anyModelChange: function(fn, opt_handler) {
return this.passBind_(this.collection.anyModelChange, arguments);
},

/** @this {mvc.Mod} */
bindAdd: function(fn, opt_handler) {
return this.passBind_(this.collection.bindAdd, arguments);
},

/** @this {mvc.Mod} */
bindRemove: function(fn, opt_handler) {
return this.passBind_(this.collection.bindRemove, arguments);
},

/** @this {mvc.Mod} */
passBind_: function(fn, args) {
var ret = fn.apply(this.collection, args);
this.bound_.push(ret);
return ret;
},

change_: goog.nullFunction
};

mvc.Filter = {

/** @this {mvc.Mod} */
init: function(collection, filter) {
this.filter_ = filter;
this.collection = collection;
this.lastFilter_ = collection.getModels(filter);
this.modelChangeFns_ = [];
this.init_();
},

/** @this {mvc.Mod} */
getModels: function() {
return this.collection.getModels(this.filter_);
},

/** @this {mvc.Mod} */
change_: function() {
if (!goog.array.equals(this.lastFilter_,
goog.array.map(this.getModels(), function(model) {
return model.cid_;
}))) {
goog.array.forEach(goog.array.clone(this.modelChangeFns_), function(fn) {
fn(this);
}, this);
}
this.lastFilter_ = goog.array.map(this.getModels(), function(model) {
return model.cid_;
});
},

/** @this {mvc.Mod} */
modelChange: function(fn, opt_handler) {
return mvc.Collection.prototype.modelChange.apply(this, arguments);
}

};
40 changes: 32 additions & 8 deletions model.js
Expand Up @@ -88,8 +88,13 @@ mvc.Model = function(opt_options) {
*/ */
this.cid_ = '' + goog.getUid(this); this.cid_ = '' + goog.getUid(this);


this.changing_ = [false];
this.waitChange_ = {};
this.waitChangeSilent_ = [true];

this.set(defaults['attr']); this.set(defaults['attr']);



this.dispatchEvent(goog.events.EventType.LOAD); this.dispatchEvent(goog.events.EventType.LOAD);
}; };
goog.inherits(mvc.Model, goog.events.EventTarget); goog.inherits(mvc.Model, goog.events.EventTarget);
Expand Down Expand Up @@ -362,6 +367,17 @@ mvc.Model.prototype.has = function(key) {
*/ */
mvc.Model.prototype.set = function(key, opt_val, opt_silent) { mvc.Model.prototype.set = function(key, opt_val, opt_silent) {


if (this.changing_[0]) {
if (goog.isString(key)) {
this.waitChange_[key] = opt_val;
this.waitChangeSilent_[0] = this.waitChangeSilent_[0] && opt_silent;
} else {
goog.object.extend(this.waitChangeSilent_, key);
this.waitChangeSilent_[0] = this.waitChangeSilent_[0] && opt_val;
}
return;
}

// handle key value as string or object // handle key value as string or object
var success = false; var success = false;
if (goog.isString(key)) { if (goog.isString(key)) {
Expand Down Expand Up @@ -451,8 +467,6 @@ mvc.Model.prototype.unset = function(key, opt_silent) {
*/ */
mvc.Model.prototype.change = function() { mvc.Model.prototype.change = function() {
this.dispatchEvent(goog.events.EventType.CHANGE); this.dispatchEvent(goog.events.EventType.CHANGE);
this.prev_ = /** @type {Object.<(Object|null)>|null} */
(goog.object.unsafeClone(this.attr_));
}; };




Expand Down Expand Up @@ -627,6 +641,7 @@ mvc.Model.prototype.revert = function(opt_silent) {
/** /**
* @param {boolean=} opt_sync pass true to del the sync to delete the model. * @param {boolean=} opt_sync pass true to del the sync to delete the model.
* @param {Function=} opt_callback function to call after sync delete finishes * @param {Function=} opt_callback function to call after sync delete finishes
* @override
*/ */
mvc.Model.prototype.dispose = function(opt_sync, opt_callback) { mvc.Model.prototype.dispose = function(opt_sync, opt_callback) {
if (opt_sync) if (opt_sync)
Expand All @@ -635,7 +650,7 @@ mvc.Model.prototype.dispose = function(opt_sync, opt_callback) {
goog.array.forEach(goog.array.clone(this.onUnload_), function(fn) { goog.array.forEach(goog.array.clone(this.onUnload_), function(fn) {
fn(this); fn(this);
}, this); }, this);
this.disposeInternal(); goog.base(this, 'dispose');
}; };




Expand Down Expand Up @@ -730,6 +745,7 @@ mvc.Model.prototype.getBinder = function(key) {
* @private * @private
*/ */
mvc.Model.prototype.change_ = function() { mvc.Model.prototype.change_ = function() {
this.changing_[0] = true;
var changes = this.getChanges(); var changes = this.getChanges();
goog.array.forEach(this.bound_, function(val) { goog.array.forEach(this.bound_, function(val) {
if (goog.array.some(val.attr, function(attr) { if (goog.array.some(val.attr, function(attr) {
Expand All @@ -741,11 +757,19 @@ mvc.Model.prototype.change_ = function() {
},this))); },this)));
} }
}, this); }, this);
if (!changes.length) if (changes.length) {
return; goog.object.forEach(this.boundAll_, function(val) {
goog.object.forEach(this.boundAll_, function(val) { val(this);
val(this); }, this);
}, this); }
this.prev_ = /** @type {Object.<(Object|null)>|null} */
(goog.object.unsafeClone(this.attr_));
this.changing_[0] = false;
var clone = goog.object.clone(this.waitChange_);
goog.object.clear(this.waitChange_);
var silent = this.waitChangeSilent_[0];
this.waitChangeSilent_[0] = true;
this.set(clone, silent);
}; };




Expand Down
2 changes: 1 addition & 1 deletion plovr/test.js
@@ -1,6 +1,6 @@
{ {
"id": "testing", "id": "testing",
"inputs": ["../collection.js", "../layout.js", "../control.js", "../mediator.js", "../model.js", "../router.js", "../store.js", "../sync/sync.js", "../sync/ajax.js"], "inputs": ["../collection.js", "../mod.js", "../layout.js", "../control.js", "../mediator.js", "../model.js", "../router.js", "../store.js", "../sync/sync.js", "../sync/ajax.js"],
"paths": ["../"], "paths": ["../"],
"output-file": "../tests/test_deps.js", "output-file": "../tests/test_deps.js",
"test-template": "../tests/test.soy" "test-template": "../tests/test.soy"
Expand Down

0 comments on commit 0b0bb0e

Please sign in to comment.