`
winxpxt
  • 浏览: 28359 次
  • 性别: Icon_minigender_2
  • 来自: 厦门
社区版块
存档分类

迷你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然后发布正式版。

0
1
分享到:
评论

相关推荐

    迷你MVVM框架---avalonjs.html

    一个迷你框架

    Android mvvm 框架,最流行的mvvm demo

    本项目“Android mvvm 框架,最流行的mvvm demo”旨在提供一个无bug的示例,帮助开发者深入理解并实践MVVM框架在Android应用中的应用。 MVVM模式源于微软的WPF开发,近年来在Android开发中逐渐流行,它通过解耦视图...

    WPF 轻量级 MVVM 框架入门 2.1.2

    **WPF轻量级MVVM框架入门2.1.2** 在Windows Presentation Foundation(WPF)开发中,MVVM(Model-View-ViewModel)模式是一种常见的设计模式,它有助于实现应用程序的视图与业务逻辑之间的解耦。MVVM通过数据绑定、...

    MVVM框架的demo

    **MVVM 框架详解** MVVM(Model-View-ViewModel)框架是现代软件开发中的一个重要概念,尤其在移动应用和Web应用开发中广泛使用。这个框架模式旨在提高应用程序的可测试性、可维护性和代码的解耦程度。在这个“MVVM...

    轻量级MVVM框架Vue.js快速上手视频教程下载

    Vue.js是一套构建用户界面的轻量级MVVM框架,与其他重量级框架不同的是, Vue.js 的核心库只关注视图层,并且非常容易学习,很容易与其它前端技术或已有的项目整合。 本系课程,主要分为两部分完成。第一部分:掌握...

    WPF中MVVM框架急速入门示例

    首先从http://mvvmlight.codeplex.com/或者http://files.cnblogs.com/chengxingliang/GalaSoft.MvvmLight.V3.rar下载它的MVVM框架下来,安装上之后,...该程序是我学习MVVM框架学习制作的小示例,很适合mvvm框架入门。

    一步一个脚印实现一个自己的简易MVVM框架

    在IT行业中,MVVM(Model-View-ViewModel)框架是前端开发的重要组成部分,尤其是在JavaScript领域。MVVM模式是由Microsoft的WPF(Windows Presentation Foundation)引入的,后来在Web开发中得到了广泛应用,例如...

    史上最强 MVVM 框架 学习必备

    【标题】: "史上最全 MVVM 框架学习指南" 在 Android 开发领域,MVVM(Model-View-ViewModel)框架已经成为了现代应用程序设计的重要组成部分。本学习资源旨在提供全面深入的 MVVM 架构理解和实践指导,帮助开发者...

    WPF mvvm框架Stylet使用教程-窗体交互用法

    **WPF MVVM框架Stylet使用教程 - 窗体交互用法** Windows Presentation Foundation (WPF) 是Microsoft提供的一种用于构建桌面应用程序的框架,它引入了Model-View-ViewModel (MVVM) 设计模式,使得UI设计和业务逻辑...

    DevExpress MVVM框架

    DevExpress MVVM框架是DevExpress提供的一个用于支持MVVM模式的开发框架,旨在简化使用DevExpress控件的MVVM应用程序开发。MVVM模式,即Model-View-ViewModel模式,是一种软件架构设计模式,通过分离用户界面的展示...

    mvvm框架整合demo

    mvvm框架整合demo 在demo内有其他的实例,和其他实用框架有利于初学都学习,也有很多的代码注释

    winform上的mvvm框架

    MVVM是一种流行的设计模式,尤其在WPF和Xamarin等框架中广泛应用,但在WinForm中相对较少见。然而,通过巧妙的实现,我们可以在WinForm上实现类似Vue的体验。 1. **MVVM模式概述**: MVVM模式分为三个主要部分:...

    winform上的mvvm框架--升级版(动态代理)

    在本文中,我们将深入探讨如何在WinForm应用中利用MVVM框架,并且通过引入Castle动态代理来提升效率和代码复用性。标题“winform上的mvvm框架--升级版(动态代理)”揭示了我们将在WinForm环境中实现一个基于MVVM...

    适用于初学者的MVVM框架

    MVVM(Model-View-ViewModel)框架是一种设计模式,尤其在现代UI开发中,如WPF(Windows Presentation Foundation)和UWP(Universal Windows Platform)应用中广泛应用。它将应用程序的界面逻辑分离开来,使开发者...

    AngularjsGoogle推出的MVVM框架

    这个框架引入了一种新的概念——Model-View-ViewModel(MVVM),使得开发人员能够更加高效地处理复杂的用户界面交互,同时保持代码的可维护性和测试性。 在传统的MVVM模式中,模型(Model)代表应用程序的数据,...

    WPF之MVVM框架实例

    WPF中的MVVM框架提供了强大的工具和结构,帮助我们构建清晰、可维护的应用程序。通过"AlarmClock"实例,我们可以看到MVVM模式如何在实践中提升开发效率和代码质量。了解并熟练运用MVVM,对于任何WPF开发者来说都是至...

    WPF MVVM开发框架

    **WPF MVVM 开发框架详解** Windows Presentation Foundation (WPF) 是 Microsoft 推出的一种用于构建桌面应用程序的用户界面框架,它集成了丰富的图形、多媒体、数据绑定和控件库,为开发者提供了强大的设计和开发...

    WPF采用MVVM框架实例

    **WPF采用MVVM框架实例** 在Windows Presentation Foundation(WPF)中,Model-View-ViewModel(MVVM)设计模式是一种广泛使用的架构模式,尤其适用于创建用户界面。它将业务逻辑、用户界面和数据绑定分离,使代码...

    ios-一个简单的MVVM框架.zip

    这个"ios-一个简单的MVVM框架.zip"文件可能包含了一个演示或实现MVVM模式的基本结构,帮助开发者更好地理解和应用这一模式。 MVVM模式的核心理念是将业务逻辑、数据和界面视图进行分离,以提高代码的可测试性和可...

    Node.js-Moer.js一个全新的基于Proxy的MVVM框架

    **Node.js与Moer.js:基于Proxy的全新MVVM框架** 在现代Web开发中,JavaScript框架扮演着至关重要的角色,它们极大地提高了开发效率并简化了前端应用的构建。Node.js作为一个强大的JavaScript运行环境,不仅在...

Global site tag (gtag.js) - Google Analytics