Skip to content

Instantly share code, notes, and snippets.

@ryasmi
Last active September 10, 2017 02:20
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ryasmi/aedb65d45b0795be92dc to your computer and use it in GitHub Desktop.
Save ryasmi/aedb65d45b0795be92dc to your computer and use it in GitHub Desktop.
Example of "true" MVC
# Model contains "operations related to the application domain" [1].
class Model
route: document.location.href.split('#').slice(1).join('#')
listeners: []
getRoute: () -> @route
setRoute: (route) ->
@route = route
@change()
change: () -> @listeners.forEach(@runListener)
onChange: (listener) -> @listeners.push(listener)
runListener: (listener) -> listener()
# View contains the "display of the application's state" [1].
class View
constructor: (@model) -> @model.onChange(@render)
render: () => console.log(@model.getRoute())
# Controller contains the "user interaction with the model and the view" [1].
class Controller
constructor: (@model, @view) ->
window.onhashchange = @changeRoute
changeRoute: (event) =>
@model.setRoute(event.newURL.split('#').slice(1).join('#'))
runApp = () ->
model = new Model()
view = new View(model)
controller = new Controller(model, view)
view.render()
runApp();
# 1. Glenn Krasner, Stephen Pope. "A Description of the Model–View–Controller User Interface Paradigm in the Smalltalk-80 System." Internet: https://web.archive.org/web/20100921030808/http://www.itu.dk/courses/VOP/E2005/VOP2005E/8_mvc_krasner_and_pope.pdf, 1988 [Oct. 5, 2015].
// Model contains "operations related to the application domain" [1].
var Model = function () {
this.route = document.location.href.split('#').slice(1).join('#');
this.listeners = [];
};
Model.prototype.getRoute = function () {
//console.error(new Error('How easy is it to trace this?'));
return this.route;
};
Model.prototype.setRoute = function (route) {
this.route = route;
this.change();
};
// "When a model is changed, a message is broadcast to notify all of its dependents" [1].
Model.prototype.change = function () {
this.listeners.forEach(this.runListener.bind(this));
};
Model.prototype.onChange = function (listener) {
this.listeners.push(listener);
};
Model.prototype.runListener = function (listener) {
listener();
};
// View contains the "display of the application's state" [1].
var View = function (model) {
this.model = model;
this.model.onChange(this.render.bind(this));
};
View.prototype.render = function () {
console.log(this.model.getRoute());
};
// Controller contains the "user interaction with the model and the view" [1].
var Controller = function (model, view) {
this.model = model;
this.view = view;
window.onhashchange = this.changeRoute.bind(this);
};
Controller.prototype.changeRoute = function (event) {
this.model.setRoute(event.newURL.split('#').slice(1).join('#'));
};
var runApp = function () {
var model = new Model();
var view = new View(model);
var controller = new Controller(model, view);
view.render();
};
runApp();
// 1. Glenn Krasner, Stephen Pope. "A Description of the Model–View–Controller User Interface Paradigm in the Smalltalk-80 System." Internet: https://web.archive.org/web/20100921030808/http://www.itu.dk/courses/VOP/E2005/VOP2005E/8_mvc_krasner_and_pope.pdf, 1988 [Oct. 5, 2015].
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment