迷你MVVM框架 avalonjs 0.85发布

本版本对循环绑定做了巨大改进,感谢@soom, @limodou, @ztz, @Gaubee 提供的大量测试文件。

  • fix scanNodes, 在循环绑定(ms-each)扫描元素节点时必须 nextTick,否则旧式IE会忙碌不过来。
  • fix ms-css ,旧式IE style[name] = value, 当value为NaN ,不带单位或不是数值什么会抛异常,需要try catch。
  • 旧式IE下有些元素的innerHTML是只读的, 因此不能一律使用innerHTML,并且有些元素的生成,如script标签是不会执行,为此我引入新的parseHTML模块来处理此事。
  • fix AMD 加载因为手误进错分支的BUG
  • fix scanExpr bug, 它在IE10有时会多生成一个绑定对象,异致不渲染错误。
  • 重构Collection内部对象与ms-each绑定,引入“事务”的概念,让其插入节点时更加智能高效。

我们看最后一条,我们可以类似纯JS操作为内存操作,DOM操作为IO操作,执行一万次前者所需的时间可能还比不上一次后者的。DOM操作的开销就是这么大。有的DOM操作还会引起reflow,这危害更大。因此明智的做法就是将要操作的节点移出DOM树。更好的办法是,此多个DOM操作合成一个,全部在文档碎片中搞完才插入DOM树。

我们看下面的注解:

<div ms-controller="box">
      <div ms-each-el="array" id="aaa">
           <p>{{$index}}----{{el}}</p>
      </div>
</div>
avalon.define("box", function(vm) {
       vm.array = [1, 2, 3, 4, 5]
})
 
 
实现过程
当扫描到div#aaa 将div#aaa的所有子节点复制一份到文档碎片vTemplate
 
执行begin命令,将vTemplate复制一个空的文档碎片vTransation( cloneNode(false) ), 设置全局变量flagTransation = true;
 
 
    开始循环数组
   
    执行insert命令
    将vTemplate复制一个文档碎片vEl( cloneNode(true) ),
  将对应的子VM与它进行扫描
  此时它的内容应为 <p>0 --- 1</p>
    将vEl appendChild到 vTemplate
    .....
    重复执行array.length次
 
执行commit命令,将vTemplate append到div#aaa节点中, 设置全局变量flagTransation = false
重新排列所有$index

在数组有关添加元素的push, unshift, splice这三个方法中,都调用了add方法,它里面就默认使用事件进行处理。

array._splice = array.splice
array.add = function(arr, insertPos) {
    insertPos = typeof insertPos === "number" ? insertPos : this.length;
    notifySubscribers(this, "begin")
    for (var i = 0, n = arr.length; i < n; i++) {
        var el = convert(arr[i])
        var pos = insertPos + i
        this._splice(pos, 0, el)
        notifySubscribers(this, "insert", pos, el)
    }
    notifySubscribers(this, "commit", insertPos)
    if (!this.stopFireLength) {
        return dynamic.length = this.length
    }
}

notifySubscribers会向上通知updateListView方法,然后让它执行相关的DOM操作

case "begin":
    list.vTransation = data.vTemplate.cloneNode(false)
    flagTransation = true
case "insert":
    //将子视图插入到文档碎片中
    var tmodel = createVModel(pos, el, list, data.args)
    var tview = data.vTemplate.cloneNode(true)
    tmodel.$view = tview
    vmodels = [tmodel].concat(vmodels)
    tmodels.splice(pos, 0, tmodel)
    scanNodes(tview, vmodels);
    data.group = ~~tview.childNodes.length //记录每个模板一共有多少子节点
    list.vTransation.appendChild(tview)
    break
case "commit":
    pos = ~~pos
    //得到插入位置 IE6-10要求insertBefore的第2个参数为节点或null,不能为undefined
    var insertNode = parent.childNodes[ data.group * pos] || null
    parent.insertBefore(list.vTransation, insertNode)
    flagTransation = false
    resetItemIndex(tmodels)
    break

嘛,不过这次改动太大了,有关Collection与bindingHandlers["each"]的代码都几乎改清光。另一个值得一提的是VM数组在腓序时,与视图的同步。这里涉及如何让一个数组基于另一个数组进行排序,我的解决方式如下:

  var aaa = [1, 2, 3, 4, 5, 1]
            var bbb = [{v: 2}, {v: 3}, {v: 1}, {v: 1}, {v: 5}, {v: 4}]
            var swapTime = 0
            var isEqual = Object.is || function(x, y) {//主要用于处理NaN 与 NaN 比较
                if (x === y) {
                    return x !== 0 || 1 / x === 1 / y;
                }
                return x !== x && y !== y;
            };
            for (var i = 0, n = bbb.length; i < n; i++) {
                var a = aaa[i];
                var b = bbb[i]
                var b = b && b.v ? b.v : b
                if (!isEqual(a, b)) {
                    console.log(++swapTime)
                    var index = getIndex(a, bbb, i);
                    var el = bbb.splice(index, 1)
                    bbb.splice(i, 0, el[0])
                }
            }
            function getIndex(a, bbb, start) {
                for (var i = start, n = bbb.length; i < n; i++) {
                    var b = bbb[i];
                    var check = b && b.v ? b.v : b
                    if (isEqual(a, check)) {
                        return i
                    }
                }
            }
            console.log(JSON.stringify(bbb))
//在框架中,aaa为数据模型M中的数组,bbb为视图模型VM中的数组

如果有更好的算法,请多多指教。

经过这次大重构后,avalon在API上基本没有变化了,未来的v0.9就是fix BUG然后发布正式版。

迷你MVVM框架在github的仓库https://github.com/RubyLouvre/avalon

官网地址http://rubylouvre.github.io/mvvm/

大家可以加入QQ群:79641290进行讨论,此群为技术群,禁水!

 
 
 
标签: avalon

迷你MVVM框架 avalonjs 0.85发布的更多相关文章

  1. 迷你MVVM框架 avalonjs 0.95发布

    迷你MVVM框架 avalonjs 0.95发布 本版本最主要的改进是ms-with 深层绑定的实现,至少,avalon1.0所有重要的feature已经开发完毕,之后就是小补小漏,性能优化了. ms ...

  2. 迷你MVVM框架 avalonjs 0.82发布

    迷你MVVM框架 avalonjs 0.82发布 本版本最大的改进是启用全新的parser. parser是用于干什么的?在视图中,我们通过绑定属性实现双向绑定,比如ms-text="fir ...

  3. 迷你MVVM框架 avalonjs 0.8发布

    本版本最重要的特性是引进了AMD规范的模块加载器,亦即原来mass Framework 的并行加载器, 不同之处,它引进了requirejs的xxx!风格的插件机制,比如要延迟到DOM树建完时触发,是 ...

  4. 迷你MVVM框架 avalonjs 0.99发布

    在本版本主要是性能优化,添加一些有用的功能(如回调什么的),离成品阶段不远了. 修正 updateViewModel bug 修正监控数组的set方法 bug 添加data-each-rendered ...

  5. 迷你MVVM框架 avalonjs 0.9发布

    本版本最大的改进是引进了ms-with绑定,现在可轻松遍历对象了. 改进列表如下: 重新使用082的scanNodes方法,因为有关旧式IE下UI渲染锁死的问题已经解决了. 优化each绑定与Coll ...

  6. 迷你MVVM框架 avalonjs 0.91发布

    本版本修了一些BUG与不合理的地方,感谢感谢ztz, 民工精髓, 姚立, qiangtou等人指正. 处理AMD加载 旧式IE下移除script节点内存泄漏的问题 fix firefox 全系列vis ...

  7. 迷你MVVM框架 avalonjs 0.92发布

    本版本最大的改进是引入ms-class的新风格支持,以前的不支持大写类名及多个类名同时操作,新风格支持了.还有对2维监控数组的支持.并着手修复UI框架. 重构 class, hover, active ...

  8. 迷你MVVM框架 avalonjs 0.93发布

    这段时间吸取@limodou, @东灵等人的意见,做了以下改进 重构isArrayLike,提高avalon.each的性能,原来avalon.each是依赖于isArrayLike来判定是循环普通对 ...

  9. 迷你MVVM框架 avalonjs 0.94发布

    本版本主要做了如下改进: 优化ms-if的逻辑,现在描述DOM的顺序是 ms-skip, ms-important, ms-controller, ms-if ... 只要元素存在ms-skip 这个 ...

随机推荐

  1. 表现层及ASP.NET MVC介绍(二)

    表现层及ASP.NET MVC介绍(二) 最近的更新速度越来越慢,主要是项目上比较忙,封装EasyUi也要花很多时间.不过大家请放心,本系列不会半途夭折,并且代码干货也会持续更新.本文继续介绍表现层和 ...

  2. Python学习笔记:概要

    1.print不同的互动解释语句输出和输出 在以下示例,我们分配字符串值到可变myString.先用print 要显示一个变量的内容, 其次是变量名,以显示. >>> myStrin ...

  3. linux 定时关机命令

    一. 关机流程 Linux 运作时, 不能够直接将电源关闭, 否则, 可能会损毁档案系统. 因此, 必须依照正常的程序关机: 观察系统使用情形(或许当时, 正有使用者做着重要的工作呢!) 通知线上使用 ...

  4. VMware Linux 下 Nginx

    负载   VMware Linux 下 Nginx 安装配置 - nginx.conf 配置 [负载两个 Tomcat] (三) Weiseditor 2014-11-26 23:42 阅读:1 评论 ...

  5. JQUERY简写案例

    源代码: <script ttype="text/javascript"> $(function(){ $(".btn").eq(0).click( ...

  6. cocos2dx对于强大的RichText控制

    最近准备做一个聊天系统,开始准备使用cocos2dx的UIRichText控制显示屏聊天,在使用中发现的结果,cocos2dx的RichText很有限.全然不具备实现聊天的功能.仅仅实现了增加文本.图 ...

  7. 【C#版本详情回顾】C#4.0主要功能列表

    诊断和性能 从 .NET Framework 4 开始,您可以获得每个应用程序域的处理器使用情况和内存使用情况估计值 通过托管承载 API.本机承载 API 以及 Windows 事件跟踪 (ETW) ...

  8. .9 png图片的制作

    在android开发的过程中我们经常因为没有好的美工图片失真,这样使界面看起来要逊色很多,有的时候可能我们会想在drawable-hdpi,ldpi,mdpi下放不同分辨率的图片,这样虽然可以有效避免 ...

  9. 【工作笔记三】非常全面的讲解Hosts文件

    原文:http://www.cnblogs.com/zgx/archive/2009/03/10/1408017.html 很奇怪有很多人不知道Hosts是什么东西.在网络病毒日渐盛行的今天,认识Ho ...

  10. php中使用随机数

    <?phpsession_start();$s = array("a","b","c","d","e&q ...