用avalon实现一个完整的todomvc(带router)
2015-02-05 17:29
232 查看
照着todomvc官网的例子,做了一个avalon版的todos,功能全都有了,而且加了router模块,比司徒大大写的都完善(≧▽≦)/~
js文件整整100行,初次使用avalon,书写过程中绕了一些弯子,不过还好最终绕回来了。整体感觉如下:
相比用jQuery,代码量下去了,编码消耗的时间貌似更多了,一来是viewmodel需要一定的逻辑设计,不是像用jQuery那样一根筋一码到底,二来是可能我对框架还不是很熟,以后熟悉后效率会飞速提升。
有一些特性并不是想当然的那样,比如对数组监控,目前只能监控length的变化,数组元素如果是对象,属性发生变化无法监控。不过可以通过其他方式变通实现。
view层能看到什么,vm层几乎都需要有一个属性与之对应,宁可多写一个属性,也不要绕别的逻辑来展示数据了。vm扁平化应该是设计思路。
demo展示如下:
你也可以点这里访问单独页面。
源码也贴一下好了:
html:
index.js:
js文件整整100行,初次使用avalon,书写过程中绕了一些弯子,不过还好最终绕回来了。整体感觉如下:
相比用jQuery,代码量下去了,编码消耗的时间貌似更多了,一来是viewmodel需要一定的逻辑设计,不是像用jQuery那样一根筋一码到底,二来是可能我对框架还不是很熟,以后熟悉后效率会飞速提升。
有一些特性并不是想当然的那样,比如对数组监控,目前只能监控length的变化,数组元素如果是对象,属性发生变化无法监控。不过可以通过其他方式变通实现。
view层能看到什么,vm层几乎都需要有一个属性与之对应,宁可多写一个属性,也不要绕别的逻辑来展示数据了。vm扁平化应该是设计思路。
demo展示如下:
你也可以点这里访问单独页面。
源码也贴一下好了:
html:
<!DOCTYPE html> <html> <head> <meta charset="utf8" /> <title>avalon todos</title> <link rel="stylesheet" href="css/base.css"> <script src="js/avalon.min.js"></script> </head> <body> <section id="todoapp" ms-controller="todos"> <header id="header"> <h1>todos</h1> <input id="new-todo" placeholder="What needs to be done?" autofocus ms-duplex="newtodo" ms-keyup="add"> </header> <section id="main" style="display: block;"> <input id="toggle-all" type="checkbox" ms-duplex-checked="allchecked"> <label for="toggle-all">Mark all as complete</label> <ul id="todo-list"> <li ms-class="completed:el.complete" ms-class-1="editing: $index === editindex" ms-repeat="todolist" ms-visible="filter===1 || filter===el.complete"> <div class="view"> <input class="toggle" type="checkbox" ms-duplex-checked="el.complete" ms-change="setcompletednum"> <label ms-dblclick="edit($index, this)">{{el.content}}</label> <button class="destroy" ms-click="$remove"></button> </div> <input class="edit" ms-duplex="el.content" ms-blur="editover"> </li> </ul> </section> <footer id="footer" style="display: block;"> <span id="todo-count"><strong>{{todolist.length}}</strong> item left</span> <ul id="filters"> <li> <a ms-class="selected:filter===1" href="#!/all" ms-click="setFilter(1)">All</a> </li> <li> <a ms-class="selected:filter===false" href="#!/active" ms-click="setFilter(false)">Active</a> </li> <li> <a ms-class="selected:filter===true" href="#!/completed" ms-click="setFilter(true)">Completed</a> </li> </ul> <button id="clear-completed" ms-click="clear">Clear completed ({{completednum}})</button> </footer> </section> <div id="info"> <p>双击列表可编辑</p> <p>前进、后退可观察路由效果</p> <p>Created by <a href="http://www.cnblogs.com/lvdabao">吕大豹</a></p> </div> <script src="js/index.js"></script> </body> </html>
index.js:
require(["mmRouter"], function(){ var model = avalon.define({ $id: "todos", newtodo: "", filter: 1, //1:all, false:active, true:completed allchecked: false, editindex: -1, //当前正在编辑的索引 todolist: [ { content: 'test111', complete: false }, { content: 'test222', complete: true } ], completednum: 0, setcompletednum: function(){ setTimeout(function(){ var count = 0; avalon.each(model.todolist, function(i, el){ if(el.complete){ count++; } }); model.completednum = count; }, 0); }, add: function(e) { if(e.keyCode === 13){ var newtodo = model.newtodo.trim(); if (!newtodo.length) { return; } model.todolist.push({ content: newtodo, complete: false }); model.newtodo = ""; } }, edit: function($index, node){ model.editindex = $index; node.parentNode.parentNode.getElementsByTagName('input')[1].focus(); }, editover: function(){ model.editindex = -1; }, clear : function(){ var actived = []; avalon.each(model.todolist, function(i, el){ if(!el.complete){ actived.push(el); } }); model.todolist = actived; model.completednum = 0; }, setFilter: function(value){ model.filter = value; } }); model.setcompletednum(); model.$watch('allchecked', function(a, b){ avalon.each(model.todolist, function(i, el){ el.complete = a; }); if(a){ model.completednum = model.todolist.length; } else{ model.completednum = 0; } }); model.todolist.$watch('length', function(){ model.setcompletednum(); }); function callback() { var filter = 1; switch(this.path){ case '\/active' : filter = false; break; case '\/completed' : filter = true; break case '\/all' : filter = 1; break; } model.setFilter(filter); } avalon.router.get("/all", callback) avalon.router.get("/active", callback) avalon.router.get("/completed", callback) avalon.history.start(); avalon.scan(); });
相关文章推荐
- 迷你MVVM框架 avalonjs 学习教程18、一步步做一个todoMVC
- 一个完整的springmvc + ajaxfileupload实现图片异步上传的案例
- hchxxzx--》一个实现图片上传/产生缩略图/在上传图片上写字功能的完整页面代码
- 用string实现的一个完整的类,包含以下操作:重载运算符 > >,< < ,string模板类,fstream对二进制数据读写
- ABAP--一个实现Search Help Exits的完整样例
- C#实现一个矩形不断向下延伸完整源程序
- 一个函数5行代码即可实现完整的面向方面AOP编程功能
- 第一次真正意义上的用VC++实现的一个完整的Win32程序-俄罗斯方块
- 使用Asp.net mvc + Linq + mvc_scaffold_gen_setup.exe 生成一个完整的家庭帐册大管家程序 之二
- [JavaScript] 你相信么,只需一个函数5行JS代码即可在Javascript中实现完整的AOP功能,
- 一个扩展的MVC框架,完整诠释MVC概念
- 用char*实现的一个完整的类,包含类的基本操作:一般构造、拷贝构造、赋值转换、重载 > >,< <
- 第一次真正意义上的用VC++实现的一个完整的Win32程序-俄罗斯方块
- ★ 在.Net中实现一个封装比较完整的FTP类——clsFTP
- 用char*实现的一个完整的类,包含类的基本操作:一般构造、拷贝构造、赋值转换、重载 > >,< <
- 实现了一个完整的chain 链表
- html dropdownlist 一个完整的javascript类实现
- ABAP--一个实现Search Help Exits的完整样例
- 使用Asp.net mvc + Linq + mvc_scaffold_gen_setup.exe 生成一个完整的家庭帐册大管家程序 之三
- ASP.NET MVC:如何实现一个自己的ModelBinder?