-
-
Save efuller/6ca1739e5f4ea25b740d0fb0a7c91fa7 to your computer and use it in GitHub Desktop.
Observable pattern in JavaScript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Observer from "../lib/Observer"; | |
class List extends Observer { | |
createMarkup(state) { | |
return `<ul> | |
${state.users.map(user => `<li>${user.name}</li>`).join("\n")} | |
</ul>`; | |
} | |
render(state, selector = "app") { | |
const markup = this.createMarkup(state); | |
const parent = document.getElementById(selector); | |
parent.innerHTML = markup; | |
} | |
// This method will be called by the Subject(state) whenever it updates. | |
// Notice how it prompts a re-render. | |
update(state) { | |
this.render(state, "user-list-container"); | |
} | |
} | |
export default List; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Observer { | |
// Gets called by the Subject::notify method. | |
update() {} | |
} | |
export default Observer; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Subject from "./Subject"; | |
class State extends Subject { | |
constructor() { | |
super(); | |
this.state = {}; | |
} | |
// Update the state. | |
// Calls the update method on each observer. | |
update(data = {}) { | |
this.state = Object.assign(this.state, data); | |
this.notify(this.state); | |
} | |
// Get the state. | |
get() { | |
return this.state; | |
} | |
} | |
export default State; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Subject { | |
constructor() { | |
this.observers = []; | |
} | |
// Add an observer to this.observers. | |
addObserver(observer) { | |
this.observers.push(observer); | |
} | |
// Remove an observer from this.observers. | |
removeObserver(observer) { | |
const removeIndex = this.observers.findIndex(obs => { | |
return observer === obs; | |
}); | |
if (removeIndex !== -1) { | |
this.observers = this.observers.slice(removeIndex, 1); | |
} | |
} | |
// Loops over this.observers and calls the update method on each observer. | |
// The state object will call this method everytime it is updated. | |
notify(data) { | |
if (this.observers.length > 0) { | |
this.observers.forEach(observer => observer.update(data)); | |
} | |
} | |
} | |
export default Subject; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment