Skip to content

Instantly share code, notes, and snippets.

@shuaibird
Last active July 31, 2017 02:57
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save shuaibird/110ce5f2ace98657bddf33598b1303b9 to your computer and use it in GitHub Desktop.
mvc example
<div>
<select id="nameList" size="5"></select>
<div id="nameCount">Total users: 0</div>
<button id="addButton">Add User</button>
<button id="removeButton">Remove User</button>
</div>
class Observer {
constructor() {
this._observers = []
}
attach(observer) {
typeof observer === 'function' && this._observers.push(observer)
}
notify(payload) {
this._observers.forEach(observer => observer(payload))
}
}
class Model {
constructor(...arg) {
this._names = Array.isArray(arg[0]) ? arg[0] : [...arg]
this.nameAdded = new Observer()
this.nameRemoved = new Observer()
}
add(name) {
this._names.push(name)
this.nameAdded.notify(this._names)
}
remove(i) {
this._names.splice(i, 1)
this.nameRemoved.notify(this._names)
}
get names() {
return this._names
}
}
class View {
constructor(elements) {
this._elements = elements
}
_refresh(names) {
this._elements.nameList.innerHTML = names.reduce((acc, cur) => acc + `<option>${cur}</option>`, '')
this._elements.nameCount.innerText = `Total users: ${names.length}`
}
init(model, controller) {
model.nameAdded.attach(names => this._refresh(names))
model.nameRemoved.attach(names => this._refresh(names))
this._elements.addButton.addEventListener('click', () => {
const name = prompt('Add a new user name: ')
name && controller.addName(name)
})
this._elements.removeButton.addEventListener('click', () => {
const i = this._elements.nameList.selectedIndex
i === -1 ? alert('No user was selected') : controller.removeName(i)
})
this._refresh(model.names)
}
}
class Controller {
constructor(model) {
this._model = model
}
addName(name) {
this._model.add(name)
}
removeName(i) {
this._model.remove(i)
}
}
(() => {
const model = new Model()
const controller = new Controller(model)
const view = new View({
nameList: document.getElementById('nameList'),
nameCount: document.getElementById('nameCount'),
addButton: document.getElementById('addButton'),
removeButton: document.getElementById('removeButton'),
})
view.init(model, controller)
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment