MVC (Model-View-Controller) separates data, presentation, and logic. Today you will implement MVC in a vanilla TypeScript app and see how Express and React map to the same concerns.
MVC (Model-View-Controller) separates data, presentation, and logic. Today you will implement MVC in a vanilla TypeScript app and see how Express and React map to the same concerns.
MVC and Architecture is one of the most important topics in Design Patterns in 5 Days. This lesson builds the foundation you need before moving to more advanced concepts — take time with each example and run the code yourself.
// Model — pure data + business rules
class TodoModel { private todos: Todo[] = []; getAll() { return [...this.todos]; } add(text: string): Todo { const todo = { id: Date.now(), text, done: false }; this.todos.push(todo); return todo; } toggle(id: number) { const todo = this.todos.find(t => t.id === id); if (todo) todo.done = !todo.done; } delete(id: number) { this.todos = this.todos.filter(t => t.id !== id); }
}
// View — renders HTML, emits user events
class TodoView { private addBtn = document.getElementById('add-btn')!; private input = document.getElementById('new-todo') as HTMLInputElement; private list = document.getElementById('todo-list')!; onAdd?: (text: string) => void; constructor() { this.addBtn.addEventListener('click', () => { this.onAdd?.(this.input.value); this.input.value = ''; }); } render(todos: Todo[]) { this.list.innerHTML = todos.map(t => \` <li data-id="\${t.id}" class="\${t.done ? 'done' : ''}"> \${t.text} </li>\`).join(''); }
}
// Controller — connects Model and View
class TodoController { constructor(private model: TodoModel, private view: TodoView) { this.view.onAdd = (text) => { this.model.add(text); this.view.render(this.model.getAll()); }; this.view.render(this.model.getAll()); }
}
new TodoController(new TodoModel(), new TodoView()); Before moving on, make sure you can answer these without looking: