Skip to content

Instantly share code, notes, and snippets.

@phloe
Last active October 10, 2015 22:48
Show Gist options
  • Save phloe/3763033 to your computer and use it in GitHub Desktop.
Save phloe/3763033 to your computer and use it in GitHub Desktop.
peter michaux's uMVC in an IIFE for readability ;D
var uMVC = (function () {
function create (constructor, prototype) {
for (var name in prototype) constructor.prototype[name] = prototype[name];
return constructor;
}
return {
Model: create(
function() {
this._observers = [];
}, {
observe: function(observer) {
this._observers.push(observer);
},
unobserve: function(observer) {
for (var i = 0, ilen = this._observers.length; i < ilen; i++) {
if (this._observers[i] === observer) {
this._observers.splice(i, 1);
return;
}
}
},
notify: function(data) {
var observers = this._observers.slice(0);
for (var i = 0, ilen = observers.length; i < ilen; i++) {
observers[i].update(data);
}
}
}
),
View: create(
function() {
this._subViews = [];
}, {
update: function() {},
getModel: function() {
return this._model;
},
setModel: function(model) {
this._setModelAndController(model, this.getController());
},
getDefaultController: function() {
return new uMVC.Controller();
},
getController: function() {
if (!this._controller) this.setController(this.getDefaultController());
return this._controller;
},
setController: function(controller) {
this._setModelAndController(this._model, controller);
},
_setModelAndController: function(model, controller) {
if (this._model !== model) {
if (this._model) this._model.unobserve(this);
if (model) model.observe(this);
this._model = model;
}
if (controller) {
controller.setView(this);
controller.setModel(model);
}
this._controller = controller;
},
getSubViews: function() {
return this._subViews.slice(0);
},
addSubView: function(subView) {
var previousSuperView = subView.getSuperView();
if (previousSuperView) previousSuperView.removeSubView(subView);
this._subViews.push(subView);
subView.setSuperView(this);
},
removeSubView: function(subView) {
for (var i = 0, ilen = this._subViews.length; i < ilen; i++) {
if (this._subViews[i] === subView) {
this._subViews[i].setSuperView(null);
this._subViews.splice(i, 1);
return;
}
}
},
setSuperView: function(superView) {
this._superView = superView;
},
getSuperView: function() {
return this._superView;
},
destroy: function() {
if (this._model) {
this._model.unsubscribe(this);
}
for (var i = 0, ilen = this._subViews.length; i < ilen; i++) {
this._subViews[i].destroy();
}
}
}
),
Controller: create(
function() {},
{
getModel: function() {
return this._model;
},
setModel: function(model) {
this._model = model;
},
getView: function() {
return this._view;
},
setView: function(view) {
this._view = view;
}
}
)
};
} ());
@petermichaux
Copy link

But this breaks the prototype.constructor property and the most important goal of <= 100 lines. ;-)

@phloe
Copy link
Author

phloe commented Apr 5, 2013

I'm slightly puzzled why I've only seen your comment just now 5 months on!?

But anyways... :)

Yes - I see what you mean. I've tried to remedy prototype.constructor with the create function. It should result in the exact same uMVC object as your original? Of course - readability went down at the same time :/

100 lines: Yes - it pained me too that I wasn't been able keep it below that mark :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment