createElement() 메서드와 appendChild() 메서드를 사용하여 요소 노드를 만들고 DOM에 추가한다.
2. 폼 전송 시 input 초기화
function App() {
const addTodo = () => {
const todo = $input.value;
$input.value = "";
};
$form.addEventListener("submit", (e) => {
e.preventDefault();
addTodo();
});
}
new App();
$form 요소 노드에 submit 이벤트를 등록한다. preventDefault() 메서드를 사용하여 DOM 요소의 기본 동작을 중단하고 addTodo() 함수를 실행한다. 이곳에서는 $input 요소 노드의 value를 todo 변수에 할당하고 value를 빈 문자열로 바꾼다.
3. 투두 데이터 업데이트
function App() {
let todos = [];
const addTodo = () => {
const todo = $input.value;
todos.push({ todo, done: false });
$input.value = "";
};
$form.addEventListener("submit", (e) => {
e.preventDefault();
addTodo();
});
}
new App();
빈 배열의 todos를 선언한다. todos는 앞으로 관리할 투두 리스트가 된다. addTodo 함수에서 push() 메서드를 사용하여 todo와 done(기본값으로 false)를 담은 객체를 추가한다.
View는 크게 두 가지의 역할을 한다. 처음 생성될 때 render() 함수를 실행하여 뼈대가 되는 html를 그린다. 이때 todo를 등록할 수 있는 form 태그와 등록된 todo가 그려질 ul 태그가 생성된다.
todoRender() 함수는 static으로 사용한다. 해당 함수를 호출하면 생성된 모든 투두를 todos로 받아 목록을 그린 후 innerHTML 프로퍼티를 사용하여 todo-list의 자식 노드로 생성한다.
5-3. Model
파일 위치: src/models/todos.js
import { $ } from "../utils/dom.js";
export default class Todos {
constructor() {
this.todos = [];
}
addTodo = () => {
const todo = $("todo-input").value;
$("todo-input").value = "";
this.todos.push({ todo, done: false });
return this.todos;
};
}
todos를 위한 Model이다. todos의 관리를 위해 constructor에서 this.todos를 배열로 선언한다.
addTodo() 함수는 현재의 input의 값을 바탕으로 새로운 todo를 추가할 때 사용된다. 반환하는 값은 추가된 todo가 포함된 todos이다.
5-4. Controller
파일 위치: src/controllers/controller.js
import Todos from "../models/todos.js";
import { $ } from "../utils/dom.js";
import View from "../views/view.js";
export default class Controller {
constructor() {
this.todosModel = new Todos();
this.view = new View();
this.eventHandler();
}
addTodo = () => {
this.todosModel.addTodo();
View.todoRender(this.todosModel.todos);
};
eventHandler = () => {
$("todo-form").addEventListener("submit", (e) => {
e.preventDefault();
this.addTodo();
});
};
}
Controller에서는 View와 Model를 연결해주고 이벤트 핸들러를 등록 및 실행한다.
현재 등록된 이밴트 핸들러는 todo-form 아이디를 가진 form이 submit되었을 때 todo를 추가하는 것 뿐이다. 해당 이벤트가 실행되면 addTodo() 함수가 호출되어 Model의 todos 업데이트하고 업데이트 된 todos를 바탕으로 View.todoRender() 함수가 실행된다.
6. Conclusion
지금까지 바닐라 자바스크립트를 사용하여 웹을 만들 땐 MVC로 나누지 않고 한 곳에 모아 구현을 해 왔다. 비슷한 기능의 함수가 따로 파일을 만들어 import하는 방식으로 나누었을 뿐이다. 이번 기회에 MVC 패턴으로 나누어 봤는데, 일단 제대로 나누었는지 부터 의문이 든다. 하지만 나름 고민하면서 어떻게 하면 효과적으로 나눌 수 있는지 고민을 하였다. 앞으로 계속 공부를 하면서 MVC 패턴을 지키며 코드 구현을 해보도록 하자.