티스토리 뷰
var Task = function() { //자바스크립트에서는 0은 false 로 인식한다. 그래서 1로 하는게 좋다. // c -complte 상태, p - progress 상태 var c = {}, p ={} var Task = function(title){ this.title = title; //아이디는 Task 만 알면 되므로 Scope 를 구성합니다. //의미상 이 Task 위 Task 가 된다. //개체는 바깥쪽과 상태로 대화하지 않는다.! 메서드로 대화한다. this._state = p }; var fn = Task.prototype; fn.isComplete = function(){ return this._state === c; }; fn.toogle = function() { if ( this._state === c) { this._state = p; } else { this._state = c; } }; fn.toString = function() { return this._title; } return Task; } //컨텍스트에 제너릭 한 Todo 로 변경 스코프에 의존하지 않는다. //투두라는 진짜의미는 TaskManager 이다. Todo의 toggle의 역확은 task안에 있는 toggle를 중계해주는 역활만 하는거구나. //개체는 식별로 비교한다. 값으로 비교하지 않는다. 예를 개체에 id값줘서 비교하는 경우 식별비고 tasks.indexOf(task); var TodoManager = (function(){ //객체 컨테스트로 지역스코프로 구성하기 , 암묵적인 컨텍스티인 this 를 사용한다. var TodoManager = function() { this._tasks = []; //taget 은 랜더러 this._renderer = null; } var fn = TodoManager.prototype; fn._render = function(){ this._renderer.render(this._tasks.slice(0)); }; fn.setRenderer = function(renderer) { if ( !(this._renderer instanceof Renderer) ) return ; this._renderer = renderer; renderer.init(this); }; fn.add = function(title) { this._tasks.push(new Task(title)); this._render(); }; fn.remove = function(task) { var ts = this._tasks; if ( this._checkTask(task) ) { ts.splice(ts.indexOf(task), 1); } this._render(); }; //메서드일까 아닐까? 일까 정답은 아닌다. 맞다 this를 사용한다. //메서드는 컨텍스트에 의존해야한다. fn._checkTask = function(task) { return !(task instanceof Task) && this._tasks.indexOf(task) > -1; }; fn.toggle = function(task) { if (this._checkTask(task)) { task.toggle(); } }; return Todo; })(); var Renderer = function{}; Renderer.prototype.init == function(todo) { this._todo = todo; this._init(); }; Renderer.prototype.render = function(tasks) { this._render(tasks); }; Renderer.prototype._init = function(todo) { throw 'init 오버라이드 해야합니다.'; }; Renderer.prototype._render = function(todo) { throw 'render 오버라이드 해야함'; }; //HTML 이 Render를 상송 받아야합니다 //코드안에 값이들어가 있으면 변경으 못한다. 하드코딩돼면안댄다다. var Html = (function(){ var Html = function() { }; //상속한다. rennder 를 var fn = Html.prototype = new Renderer(); fn._init = function(todo){ }; fn._render = function(todo){ }; return Html; })(); //코드에는 의미가 다 표현해야한다. var Item = (function() { var items = {}; var Item = function(selector){ if ( items[selector]) throw '이미 존재하는 selector'; this._el = itmes[selector] = selector; }; var fn = Item.prototype; fn.init = function(){ var el; this._el = document.querySelector(this._el); if (el.parentNode) el.parentNode.removeChild(el); }; fn.add = function(task){ this._el = this._el.cloneNode(true); //객체가 문자로 바꿔야만 innerHtml만댄다. 기본스트링반환메서드는 toString() el.querySelector('p').innerHTML = task; var todo = this._todo; var btns = el.querySelectorAll('input'); btns[0].onclick = function(){ todo.toggle(task); }; btns[1].onclick = function(){ todo.remove(task); }; return el; }; return Item; })(); //리스트는 컨테이만 책임지고 모든행위는 item에 넘긴다. var List = (function(){ var containers = {}; var List = function(selector, item){ if ( containers[selector]) throw '이미 컨테이너가 존재합니다.'; this._container = containers[selector] = selector; this._item = item; }; var fn = List.prototype; fn.init = function(manager){ //셀렉터가 하나만 나올수 있는걸 보자장해야한다. this._container = document.querySelector(this._container); this._item.init(); }; fn.add = function(task){ //item에 떠밀기를 한다. this._container.appendChild(this._item.add(task)); }; fn.clear = function(){ this._container.innerHTML = ''; }; return List; })(); //리스트를 관리합니다. var ListManager = (function(){ var ListManager = function(add, plist, clist){ this._add = add; this._pList = plist; this._cList = clist; }; var fn = ListManger.prototype = new Renderer(); // ListManger 는 각각 메서드에 초기화하는 역활만 한다. fn._init = function(){ this._add(this); this._pList.init(this); this._cList.init(this); }; fn._render = function(tasks) { var task; c this._pList.clear(); this._cList.clear(); for ( var i = 0; i < tasks.length; i++ ) { task = task[i]; if ( task.isComplete()) { this._cList.add(task); } else { this._pList.add(task); } } } return ListManager; })(): //호스트 코드 작성 훔 var todo = new TaskManager(); todo.setRenderer( new ListManager( function(todo) { var title = document.querySelector('#todo .title'); document.querySelector('#todo .add').onsubmit = function(){ var v = title.value.trim(); if (v) { todo.add(v) } title.value = ''; return false; }; }, new List('#todo .progress', new Item('#todo .progress li')), new List('#todo .complete', new Item('#todo .complete li')) ));
'웹개발 > Javascript' 카테고리의 다른 글
ES6 TODO 1 (0) | 2019.04.13 |
---|---|
15 indexOf 여러 방법으로 사용하기 (0) | 2016.01.20 |
console.time( label ) 활용한 성능 시간 측정 방법 (0) | 2016.01.15 |
05. Undefined 와 Null 의 차이 (0) | 2016.01.14 |
03. 중첩 조건문(if) 개선하기 (0) | 2016.01.14 |
댓글