照着todomvc官网的例子,做了一个avalon版的todos,功能全都有了,而且加了router模块,比司徒大大写的都完善(≧▽≦)/~

  js文件整整100行,初次使用avalon,书写过程中绕了一些弯子,不过还好最终绕回来了。整体感觉如下:

  1. 相比用jQuery,代码量下去了,编码消耗的时间貌似更多了,一来是viewmodel需要一定的逻辑设计,不是像用jQuery那样一根筋一码到底,二来是可能我对框架还不是很熟,以后熟悉后效率会飞速提升。
  2. 有一些特性并不是想当然的那样,比如对数组监控,目前只能监控length的变化,数组元素如果是对象,属性发生变化无法监控。不过可以通过其他方式变通实现。
  3. view层能看到什么,vm层几乎都需要有一个属性与之对应,宁可多写一个属性,也不要绕别的逻辑来展示数据了。vm扁平化应该是设计思路。

  demo展示如下:

  

  你也可以点这里访问单独页面。

  源码也贴一下好了:

  html:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf8" />
  5. <title>avalon todos</title>
  6. <link rel="stylesheet" href="css/base.css">
  7. <script src="js/avalon.min.js"></script>
  8. </head>
  9. <body>
  10. <section id="todoapp" ms-controller="todos">
  11. <header id="header">
  12. <h1>todos</h1>
  13. <input id="new-todo" placeholder="What needs to be done?" autofocus ms-duplex="newtodo" ms-keyup="add">
  14. </header>
  15. <section id="main" style="display: block;">
  16. <input id="toggle-all" type="checkbox" ms-duplex-checked="allchecked">
  17. <label for="toggle-all">Mark all as complete</label>
  18. <ul id="todo-list">
  19. <li ms-class="completed:el.complete" ms-class-1="editing: $index === editindex" ms-repeat="todolist" ms-visible="filter===1 || filter===el.complete">
  20. <div class="view">
  21. <input class="toggle" type="checkbox" ms-duplex-checked="el.complete" ms-change="setcompletednum">
  22. <label ms-dblclick="edit($index, this)">{{el.content}}</label>
  23. <button class="destroy" ms-click="$remove"></button>
  24. </div>
  25. <input class="edit" ms-duplex="el.content" ms-blur="editover">
  26. </li>
  27. </ul>
  28. </section>
  29. <footer id="footer" style="display: block;">
  30. <span id="todo-count"><strong>{{todolist.length}}</strong> item left</span>
  31. <ul id="filters">
  32. <li>
  33. <a ms-class="selected:filter===1" href="#!/all" ms-click="setFilter(1)">All</a>
  34. </li>
  35. <li>
  36. <a ms-class="selected:filter===false" href="#!/active" ms-click="setFilter(false)">Active</a>
  37. </li>
  38. <li>
  39. <a ms-class="selected:filter===true" href="#!/completed" ms-click="setFilter(true)">Completed</a>
  40. </li>
  41. </ul>
  42. <button id="clear-completed" ms-click="clear">Clear completed ({{completednum}})</button>
  43. </footer>
  44. </section>
  45. <div id="info">
  46. <p>双击列表可编辑</p>
  47. <p>前进、后退可观察路由效果</p>
  48. <p>Created by <a href="http://www.cnblogs.com/lvdabao">吕大豹</a></p>
  49. </div>
  50.  
  51. <script src="js/index.js"></script>
  52. </body>
  53. </html>

  index.js:

  1. require(["mmRouter"], function(){
  2. var model = avalon.define({
  3. $id: "todos",
  4. newtodo: "",
  5. filter: 1, //1:all, false:active, true:completed
  6. allchecked: false,
  7. editindex: -1, //当前正在编辑的索引
  8. todolist: [
  9. {
  10. content: 'test111',
  11. complete: false
  12. },
  13. {
  14. content: 'test222',
  15. complete: true
  16. }
  17. ],
  18. completednum: 0,
  19. setcompletednum: function(){
  20. setTimeout(function(){
  21. var count = 0;
  22. avalon.each(model.todolist, function(i, el){
  23. if(el.complete){
  24. count++;
  25. }
  26. });
  27. model.completednum = count;
  28. }, 0);
  29. },
  30. add: function(e) {
  31. if(e.keyCode === 13){
  32. var newtodo = model.newtodo.trim();
  33. if (!newtodo.length) {
  34. return;
  35. }
  36. model.todolist.push({
  37. content: newtodo,
  38. complete: false
  39. });
  40. model.newtodo = "";
  41. }
  42. },
  43. edit: function($index, node){
  44. model.editindex = $index;
  45. node.parentNode.parentNode.getElementsByTagName('input')[1].focus();
  46. },
  47. editover: function(){
  48. model.editindex = -1;
  49. },
  50. clear : function(){
  51. var actived = [];
  52. avalon.each(model.todolist, function(i, el){
  53. if(!el.complete){
  54. actived.push(el);
  55. }
  56. });
  57. model.todolist = actived;
  58. model.completednum = 0;
  59. },
  60. setFilter: function(value){
  61. model.filter = value;
  62. }
  63.  
  64. });
  65. model.setcompletednum();
  66. model.$watch('allchecked', function(a, b){
  67. avalon.each(model.todolist, function(i, el){
  68. el.complete = a;
  69. });
  70. if(a){
  71. model.completednum = model.todolist.length;
  72. }
  73. else{
  74. model.completednum = 0;
  75. }
  76. });
  77. model.todolist.$watch('length', function(){
  78. model.setcompletednum();
  79. });
  80. function callback() {
  81. var filter = 1;
  82. switch(this.path){
  83. case '\/active' :
  84. filter = false;
  85. break;
  86. case '\/completed' :
  87. filter = true;
  88. break
  89. case '\/all' :
  90. filter = 1;
  91. break;
  92. }
  93. model.setFilter(filter);
  94. }
  95. avalon.router.get("/all", callback)
  96. avalon.router.get("/active", callback)
  97. avalon.router.get("/completed", callback)
  98. avalon.history.start();
  99. avalon.scan();
  100. });

用avalon实现一个完整的todomvc(带router)的更多相关文章

  1. 《Java从入门到失业》第四章:类和对象(4.3):一个完整的例子带你深入类和对象

    4.3一个完整的例子带你深入类和对象 到此为止,我们基本掌握了类和对象的基础知识,并且还学会了String类的基本使用,下面我想用一个实际的小例子,逐步来讨论类和对象的一些其他知识点. 4.3.1需求 ...

  2. 【如何快速的开发一个完整的iOS直播app】(播放篇)

    原文转自:袁峥Seemygo    感谢分享.自我学习 前言 在看这篇之前,如果您还不了解直播原理,请查看上篇文章如何快速的开发一个完整的iOS直播app(原理篇) 开发一款直播app,集成ijkpl ...

  3. 【如何快速的开发一个完整的iOS直播app】(原理篇)

    原文转自:袁峥Seemygo    感谢分享.自我学习 目录 [如何快速的开发一个完整的iOS直播app](原理篇) [如何快速的开发一个完整的iOS直播app](播放篇) [如何快速的开发一个完整的 ...

  4. Django1.8教程——从零开始搭建一个完整django博客(一)

    第一个Django项目将是一个完整的博客网站.它和我们博客园使用的博客别无二致,一样有分类.标签.归档.查询等功能.如果你对Django感兴趣的话,这是一个绝好的机会.该教程将和你一起,从零开始,搭建 ...

  5. 如何快速的开发一个完整的iOS直播app(原理篇)

    目录 [如何快速的开发一个完整的iOS直播app](原理篇) [如何快速的开发一个完整的iOS直播app](播放篇) [如何快速的开发一个完整的iOS直播app](采集篇) 前言 大半年没写博客了,但 ...

  6. 开发一个完整的JavaScript组件

    作为一名开发者,大家应该都知道在浏览器中存在一些内置的控件:Alert,Confirm等,但是这些控件通常根据浏览器产商的不同而形态各异,视觉效果往往达不到UI设计师的要求.更重要的是,这类内置控件的 ...

  7. SQL Server Database 维护计划创建一个完整的备份策略

     SQL Server维护计划Maintenance Plan这是一个非常有用的维护工具,能够完成大部分的数据库维护任务,通过这些功能包.您可以省略大量的编码时间. 介绍的不是非常多,特此补上一篇 ...

  8. 一个完整的Installshield安装程序实例—艾泽拉斯之海洋女神出品(四) --高级设置二

    原文:一个完整的Installshield安装程序实例-艾泽拉斯之海洋女神出品(四) --高级设置二 上一篇:一个完整的安装程序实例—艾泽拉斯之海洋女神出品(三) --高级设置一4. 根据用户选择的组 ...

  9. 一个完整的Node.js RESTful API

    前言 这篇文章算是对Building APIs with Node.js这本书的一个总结.用Node.js写接口对我来说是很有用的,比如在项目初始阶段,可以快速的模拟网络请求.正因为它用js写的,跟i ...

随机推荐

  1. keepalived健康检查方式

    keepalived对后端realserver的健康检查方式主要有以下几种: TCP_CHECK:工作在第4层,keepalived向后端服务器发起一个tcp连接请求,如果后端服务器没有响应或超时,那 ...

  2. 手势估计- Hand Pose Estimation

    http://blog.csdn.net/myarrow/article/details/51933651 1. 目前进展 1.1 相关资料      1)HANDS CVPR 2016      2 ...

  3. mysql 行变列(多行变成一行/多行合并成一行/多行合并成多列/合并行)

    数据库结构如图: 而我想让同一个人的不同成绩变成此人在这一行不同列上显示出来,此时分为2中展现: 第一种展现如图----[多行变一列](合并后的数据在同一列上): sql如下: select name ...

  4. 如何辨别具体的一种SaaS是否安全?

    如何辨别具体的一种SaaS是否安全,需要把握以下几点: 1.传输协议加密 首先,要看SaaS产品提供使用的协议,是https://还是一般的http://,别小看这个s,这表明所有的数据在传输过程中都 ...

  5. 删除所选项(附加搜索部分的jquery)

    1.视图端(views)的配置为: <script> $(document).ready(function() { $("#info-grid").kendoGrid( ...

  6. MySQL提示符含义

    http://www.splaybow.com/post/mysql-prompt-introduce.html mysql> 准备好接受新命令. 说明:正常等待输入的提示符. -> 等待 ...

  7. 1236 - Pairs Forming LCM -- LightOj1236 (LCM)

    http://lightoj.com/volume_showproblem.php?problem=1236 题目大意: 给你一个数n,让你求1到n之间的数(a,b && a<= ...

  8. hdoj 2066 一个人的旅行

    Problem Description 虽然草儿是个路痴(就是在杭电待了一年多,居然还会在校园里迷路的人,汗~),但是草儿仍然很喜欢旅行,因为在旅途中 会遇见很多人(白马王子,^0^),很多事,还能丰 ...

  9. Android自定义View的实现方法,带你一步步深入了解View(四)

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/17357967 不知不觉中,带你一步步深入了解View系列的文章已经写到第四篇了,回 ...

  10. android 模拟器上网问题

    android 模拟器上网问题 1.配置Adroid环境变量(Win7为例) ,启动模拟器 第一步:桌面右键——>我的电脑——>高级系统设置    第二步:高级——>环境变量——&g ...