• 迷你MVVM框架 avalonjs 0.82发布


    本版本最大的改进是启用全新的parser。

    parser是用于干什么的?在视图中,我们通过绑定属性实现双向绑定,比如ms-text="firstName", ms-html="sex + '士'", ms-visible="Math.abs(toggle + 2000) >= 20", 我们需要将它们转换为求值函数。我们通过ms-controller="vm"来绑定ViewModel,比如vm = { firstName: '司徒'}, 那么对于上面的第一个绑定,我们想让它变成函数,以前是这样实现的:

                function anonymous(vm1372575919386) {
                    with (vm1372575919386) {
                        var ret1372575919386 = firstName
                    }
                    return ret1372575919386
                }
    

    然后视图刷新函数会将vm传入此函数,var ret = anonymous(vm), 得到'司徒',然后node.value = ret(注,这里的node 为文本节点,它在扫描DOM树时被抽取出来),完成视图的最少化刷新。这个过程中如何将绑定属性的值转换为求值函数显然是重中之重。

    之前的parser,正如大家看到的那样,非常简单,然后with表达式一包,然后返回结果。但with在ES5的严格模式下运行不了,也一直为性能洁癖人士所不齿。并且它存在一个问题,它的依赖收集并不完整。比如下面这种

         

    aaa {{test1 && test2}}

    上面的插值表达式是一个文本绑定,转换为求值函数时,为:

                function anonymous(vm1372575919386) {
                    with (vm1372575919386) {
                        var ret1372575919386 = test1 && test2
                    }
                    return ret1372575919386
                }
    

    当一开始test1为false, test2为true时,由于短路与的关系,我们并没有对test2进行取值。由于avalon只在求值函数的第一次执行时收集依赖,在依赖是通过求值赋值语句实现的,而这时,我们就肯定遗漏了test2了。因此一个全新的parser就迫在眉睫了。

    新的parser的实现思路时,设法抽取到绑定值中的变量,然后转换为赋值语句,放到求值函数的最前面,这样就不会遗漏任何依赖了。问题是如何得到这些变量。比如上面三例,它们的变量依次是firstName, sex, toggle,我们要设法去掉所有杂质,首先要去掉注释,字符串,正则这些字面量,然后是加减乘除这些操作符,然后是if, while, for, undefined, void 等关键字,然后是作为某个对象的属性或方法存在的语句,如.prop,然后逗号这样用于断句用的符号。但即使这样,还会留下像Math, String等全局变量,这时我们就通过vm取hasOwnerProperty进行排除。

    下面就是通过新的parser转换得到的求值函数。

                function anonymous(vm1372575919386) {
                    var firstName =  vm1372575919386.firstName
                  
                    return firstName 
                }
                function anonymous(vm1372575919386) {
                    var test1=  vm1372575919386.test1, test2 = vm1372575919386.test2
                  
                    return test1 && test2
                }
    

    并且进一步,我们可以在里面塞进'use strict'来提高性能。

                function anonymous(vm1372575919386) {
                    'use strict';
                    var firstName =  vm1372575919386.firstName
                  
                    return firstName 
                }
                function anonymous(vm1372575919386) {
                    'use strict';
                    var test1=  vm1372575919386.test1, test2 = vm1372575919386.test2
                  
                    return test1 && test2
                }
    

    如何存在过滤器

       
    {{ new Date | date('dd MM yyyy') }}
    
                function anonymous(vm1372896828095_0, filters1372896828095) {
                    'use strict';
                    var ret1372896828095 = new Date
                    if (filters1372896828095.date) {
                        try {
                            ret1372896828095 = filters1372896828095.date(ret1372896828095, 'dd MM yyyy')
                        } catch (e) {
                        }
                    }
                    return ret1372896828095
                }
    

    凭借着此新parser,avalon又有了一个质的提高。有关的parser的实现,可以详看该issue

    读者们也可以对比angular的parser实现, avalon的是非常小巧的。

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

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

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

  • 相关阅读:
    重载小于号
    无聊的会议
    程序内存和时间
    对拍
    读入和输出优化
    codevs 3269 混合背包
    清北第三套题
    codevs 2188 最长上升子序列
    清北第二套题
    [COGS896] 圈奶牛
  • 原文地址:https://www.cnblogs.com/rubylouvre/p/3170795.html
Copyright © 2020-2023  润新知