项目github地址https://github.com/tastejs/todomvc/
排除通用的css样式文件和引用的js库文件,仅看html和js
1.1 knockoutjs版todo app文件结构
knockoutjs
--index.html
--js
----app.js
1.2 backbonejs版todo app文件结构
backbonejs
--index.html
--js
----collections
------todos.js
----models
------todo.js
----routers
------router.js
----views
------app-view.js
------todo-view.js
----app.js
1.3 angularjs版todo app文件结构
angularjs
--index.html
--js
----controllers
------todoCtrl.js
----directives
------todoEscape.js
----services
------todoStorage.js
----app.js
二、knockout版todo主要内容
knockout版todo app实现细节,之前有文讲过,详情见《用KnockoutJS实现ToDoMVC代码分析》
从上文的文件结构可知,其业务代码只有app.js,html view只有index.html
2.1 视图代码index.html
knockout在html原有属性基础上,新增了data-bind属性
data-bind属性作为knockout与html交互的入口,内置了如下若干指令
- visible binding
- text binding
- html binding
- css binding
- style binding
- attr binding
除了上述内置指令,knockout也可以添加自定义指令,如html中出现的enterKey、escapeKey和selectAndFocus指令
<section id="todoapp"> <header id="header"> <h1>todos</h1> <input id="new-todo" data-bind="value: current, valueUpdate: 'afterkeydown', enterKey: add" placeholder="What needs to be done?" autofocus> </header> <section id="main" data-bind="visible: todos().length"> <input id="toggle-all" data-bind="checked: allCompleted" type="checkbox"> <label for="toggle-all">Mark all as complete</label> <ul id="todo-list" data-bind="foreach: filteredTodos"> <li data-bind="css: { completed: completed, editing: editing }"> <div class="view"> <input class="toggle" data-bind="checked: completed" type="checkbox"> <label data-bind="text: title, event: { dblclick: $root.editItem }"></label> <button class="destroy" data-bind="click: $root.remove"></button> </div> <input class="edit" data-bind="value: title, valueUpdate: 'afterkeydown', enterKey: $root.saveEditing, escapeKey: $root.cancelEditing, selectAndFocus: editing, event: { blur: $root.stopEditing }"> </li> </ul> </section> <footer id="footer" data-bind="visible: completedCount() || remainingCount()"> <span id="todo-count"> <strong data-bind="text: remainingCount">0</strong> <span data-bind="text: getLabel(remainingCount)"></span> left </span> <ul id="filters"> <li> <a data-bind="css: { selected: showMode() == 'all' }" href="#/all">All</a> </li> <li> <a data-bind="css: { selected: showMode() == 'active' }" href="#/active">Active</a> </li> <li> <a data-bind="css: { selected: showMode() == 'completed' }" href="#/completed">Completed</a> </li> </ul> <button id="clear-completed" data-bind="visible: completedCount, click: removeCompleted">Clear completed</button> </footer> </section>