Created
February 21, 2015 12:09
-
-
Save masahirompp/0fc24cd168651bdcc2f4 to your computer and use it in GitHub Desktop.
javascript mvc (no framework) http://jsfiddle.net/54sjqL6z/
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
(function(todo) { | |
'use strict'; | |
// viewの追加イベントを監視。TodoListに新規Todoを追加する。 | |
todo.View.on('add', function(description) { | |
todo.TodoList.add(new todo.Todo(todo.TodoList.length, description)); | |
todo.View.clearInput(); | |
}); | |
// viewの変更イベントを監視。モデルの状態を更新を命令。 | |
todo.View.on('change', function(index) { | |
todo.TodoList[index].done(); | |
}); | |
})(this.todo); |
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
<!DOCTYPE html> | |
<html lang="ja"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Todo MVC Sample</title> | |
<style> | |
.completed { | |
text-decoration:line-through; | |
} | |
</style> | |
</head> | |
<body> | |
<div> | |
<input type="text" id="todoInput"> | |
</div> | |
<div> | |
<ul id="todoList"></ul> | |
</div> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore.js"></script> | |
<script src="./util.js"></script> | |
<script src="./model.js"></script> | |
<script src="./view.js"></script> | |
<script src="./controller.js"></script> | |
</body> | |
</html> |
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
(function(_, util, exports) { | |
'use strict'; | |
// Model | |
var Todo = _.extend(function(id, description) { | |
this.id = id; | |
this.description = description; | |
this.complete = false; | |
}, util.events()); | |
Todo.prototype.done = function() { | |
this.complete = true; | |
Todo.trigger('change', this); | |
}; | |
// Collection | |
var TodoList = _.extend([], util.events()); | |
TodoList.add = function(todo) { | |
this.push(todo); | |
this.trigger('change', TodoList); | |
}; | |
// export | |
exports.Todo = Todo; | |
exports.TodoList = TodoList; | |
})(this._, this.util, this.todo = this.todo || {}); |
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
(function(_, exports) { | |
'use strict'; | |
exports.events = function() { | |
var events = {}; | |
return { | |
on: function(name, func) { | |
(events[name] || (events[name] = [])) | |
.push(func); | |
return this; | |
}, | |
trigger: function(name /*, ...args */ ) { | |
var funcs = events[name] || []; | |
var args = _.rest(arguments); | |
funcs.forEach(function(func) { | |
setTimeout(function() { | |
func.apply(null, args); | |
}, 0); | |
}); | |
return this; | |
} | |
}; | |
}; | |
})(this._, this.util = this.util || {}); |
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
(function(_, util, exports) { | |
'use strict'; | |
// モデルの参照 | |
var Todo = exports.Todo; | |
var TodoList = exports.TodoList; | |
// DOM参照 | |
var input = window.document.getElementById('todoInput'); | |
var ul = window.document.getElementById('todoList'); | |
var View = _.extend({}, util.events()); | |
var todoHtml = _.template('<li id="todo_<%= id %>" <% if(complete) { %>class="completed" <% }%>><%= description %></li>'); | |
// DOM操作 TodoListを描画 | |
function render(todoList) { | |
ul.innerHTML = todoList.reduce(function(html, todo) { | |
return html + todoHtml(todo); | |
}, ''); | |
} | |
// DOM操作 Todoの状態を更新 | |
function complete(todo) { | |
var target = window.document.getElementById('todo_' + todo.id); | |
target.className = todo.complete ? 'completed' : ''; | |
} | |
// DOM操作 入力をクリア | |
function clearInput() { | |
input.value = ''; | |
} | |
View.clearInput = clearInput; // export | |
// モデルを監視 | |
Todo.on('change', complete); | |
TodoList.on('change', render); | |
// Event通知 | |
input.addEventListener('keydown', function(e) { | |
if (e.keyCode === 13 && e.target.value) View.trigger('add', e.target.value); // inputでENTERが押下された場合に通知 | |
}); | |
ul.addEventListener('click', function(e) { | |
if (e.target.tagName.toLowerCase() === 'li') { | |
View.trigger('change', _.last(e.target.id.split('_'))); // 各アイテムがクリックされた時に通知 | |
} | |
}); | |
// export | |
exports.View = View; | |
})(this._, this.util, this.todo); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment