I'm learning to use MVC in my JavaScript apps and I thought it might be good practice to write my own MVC implementation. I'd like to know if you see any ways I could improve it or any potential issues I could run into using it.
class Model {
constructor() {
this.listenerStorage = {};
}
trigger(event) {
if (this.listenerStorage[event]) {
this.listenerStorage[event].forEach((callback) => {
callback();
});
}
}
on(event, callback) {
this.listenerStorage[event] = this.listenerStorage[event] || [];
this.listenerStorage[event].push(callback);
}
set(propObj, value) {
if (value) { // propObj is just a string
this[propObj] = value;
this.trigger("change:" + propObj);
} else { // propObj is an object with multiple values to change
for (var prop in propObj) {
this[prop] = propObj[prop];
this.trigger("change:" + prop);
}
}
this.trigger("all");
}
}
class User extends Model {
constructor(firstName, lastName, age) {
super();
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
}
class Controller {
constructor(user) {
this.user = user;
this.initializeListeners();
}
initializeListeners() {
document.getElementById("submit").addEventListener("click", (event) => {
event.preventDefault();
this.updateUser();
return false;
});
}
updateUser() {
let firstNameInput = document.getElementById("firstNameInput");
let lastNameInput = document.getElementById("lastNameInput");
let ageInput = document.getElementById("ageInput");
const newFirstName = firstNameInput.value;
const newLastName = lastNameInput.value;
const newAge = ageInput.value;
this.user.set({
"firstName": newFirstName,
"lastName": newLastName,
"age": newAge
});
}
}
class View {
constructor(user) {
this.user = user;
this.initializeListeners();
this.updateInputs();
this.displayGreeting();
}
initializeListeners() {
this.user.on("all", () => {
this.displayGreeting();
});
}
displayGreeting() {
let greeting = `<p>Hello ${this.user.firstName} ${this.user.lastName}! You're ${this.user.age} years old.</p>`;
let greetingElem = document.createElement("p");
greetingElem.innerHTML = greeting;
let greetingWrapper = document.getElementById("greeting");
greetingWrapper.innerHTML = null;
greetingWrapper.appendChild(greetingElem);
}
updateInputs(user) {
document.getElementById("firstNameInput").value = this.user.firstName;
document.getElementById("lastNameInput").value = this.user.lastName;
document.getElementById("ageInput").value = this.user.age;
}
}
document.addEventListener("DOMContentLoaded", () => {
let user = new User("Joe", "Bob", 21);
let view = new View(user);
let controller = new Controller(user);
});
input,
label,
button,
p {
float: left;
clear: left;
margin: 5px;
}
<form>
<h3>User</h3>
<label for="firstName">First Name:</label>
<input type="text" id="firstNameInput" name="firstName">
<label for="lastName">Last Name:</label>
<input type="text" id="lastNameInput" name="lastName">
<label for="age">Age:</label>
<input type="text" id="ageInput" name="age">
<button id="submit">Submit</button>
</form>
<div id="greeting">
</div>
<p>Hello ${this.user.firstName} ${this.user.lastName}! You're ${this.user.age} years old.</p>
; let greetingElem = document.createElement("p"); " results in a p-tag which is nested within another p-tag. No valid HTML as far as I know. Why not just : "Hello ${this.user.firstName} ${this.user.lastName}! You're ${this.user.age} years old.
" ? This is then enclosed by the created p-tag. – mizech Feb 11 at 13:35