zoukankan      html  css  js  c++  java
  • 用avalon实现一个完整的todomvc(带router)

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

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

    1. 相比用jQuery,代码量下去了,编码消耗的时间貌似更多了,一来是viewmodel需要一定的逻辑设计,不是像用jQuery那样一根筋一码到底,二来是可能我对框架还不是很熟,以后熟悉后效率会飞速提升。
    2. 有一些特性并不是想当然的那样,比如对数组监控,目前只能监控length的变化,数组元素如果是对象,属性发生变化无法监控。不过可以通过其他方式变通实现。
    3. 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();
    });
  • 相关阅读:
    spring源码怎么解决循环依赖?
    观察者模式
    单例模式
    Python 列表(List)
    python字符串(str)
    内置函数
    python运算符
    函数名的应用 闭包 迭代器
    生成器,推导式
    python的起源
  • 原文地址:https://www.cnblogs.com/lvdabao/p/4275404.html
Copyright © 2011-2022 走看看