Skip to content

Instantly share code, notes, and snippets.

@adrianvlupu
Created December 11, 2013 17:39
Show Gist options
  • Save adrianvlupu/7914935 to your computer and use it in GitHub Desktop.
Save adrianvlupu/7914935 to your computer and use it in GitHub Desktop.
JS MVC
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="jquery-2.0.3.min.js"></script>
<script src="underscore.js"></script>
<script src="backbone.js"></script>
<script>
//#region eventHandler
var eventHandler = function (sender) {
this.sender = sender;
this.listeners = [];
};
eventHandler.prototype = {
attach: function (listener) {
this.listeners.push(listener);
},
trigger: function (args) {
for (var i = 0; i < this.listeners.length; i++) {
this.listeners[i](this.sender, args);
}
}
};
//#endregion
//#region Service
var service = function () {
var self = this;
this.controllers = {};
};
service.prototype = {
addController: function (label, controller) {
this.controllers[label] = controller;
controller.service = this;
}
};
//#endregion
//#region Models
var taskModel = function () {
var self = this;
var _isCompleted = true;
this.onCompletedChanged = new eventHandler(this);
Object.defineProperty(this, 'isCompleted', {
get: function () { return _isCompleted; },
set: function (value) {
_isCompleted = value;
self.onCompletedChanged.trigger();
},
enumerable: true
});
var _text = '';
this.onTextChanged = new eventHandler(this);
Object.defineProperty(this, 'text', {
get: function () { return _text; },
set: function (value) {
_text = value;
self.onTextChanged.trigger();
}
});
//this.modelState = new modelState();
};
var taskListModel = function () {
var self = this;
this.onCollectionChanged = new eventHandler(this);
this.collection = [];
this.add = function (o) {
self.collection.push(o);
self.onCollectionChanged.trigger();
}
this.remove = function (index) {
self.collection.splice(index, 1);
self.onCollectionChanged.trigger();
}
};
//#endregion
//#region Views
var taskView = function (model, controls) {
var ctl = controls || {
txtTask: $('#txtTask'),
btnAdd: $('#btnAddTask')
};
var self = this;
//view methods
this.clearControls = function () {
ctl.txtTask.val('');
};
//view events
this.onAdd = new eventHandler(this);
ctl.btnAdd.click(function (e) {
self.onAdd.trigger({ text: ctl.txtTask.val() });
self.clearControls();
});
}
var taskListView = function (model, controls) {
var ctl = controls || {
divTasks: $('#divTasks')
};
var self = this;
//view methods
this.updateCollection = function (s, e) {
ctl.divTasks.empty();
for (var i = 0; i < model.collection.length; i++) {
//use templateing engine of your choice
var template = '<input type="checkbox" {{checked}}/><label>{{text}}</label><br/>';
template = template.replace(/{{checked}}/g, model.collection[i].isCompleted ? 'checked="checked"' : '')
template = template.replace(/{{text}}/g, model.collection[i].text)
ctl.divTasks.append(template);
}
};
//attach view to model events
model.onCollectionChanged.attach(this.updateCollection);
}
//#endregion
//#region Controllers
var taskController = function (m, v) {
var self = this;
this.model = m; this.view = v;
//attach to view events
this.view.onAdd.attach(function (s, e) {
self.service.controllers.taskListController.add({ text: e.text });
});
};
var taskListController = function (m, v) {
var self = this;
this.model = m; this.view = v;
this.add = function (o) {
self.model.add(o);
}
};
//#endregion
$(function () {
var tm = new taskModel();
var tv = new taskView(tm);
var tlm = new taskListModel();
var tlv = new taskListView(tlm);
var tc = new taskController(tm, tv);
var tlc = new taskListController(tlm, tlv);
var s = new service();
s.addController('taskController', tc);
s.addController('taskListController', tlc);
});
</script>
</head>
<body>
<input type="text" id="txtTask" /><input type="button" id="btnAddTask" value="Add" />
<div id="divTasks">
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment