• avalon最佳实践


    最近从angular的QQ群与新浪微博拉了许多人来用我的avalon,成为第一批登上方舟,脱离DOM苦海的人。短短三个月内,5群的朋友也搞出几个切实实行的案例了。为应对粉丝们高益高涨的热情,遂放出此文章。

    avalon的数据绑定需要经过扫描才能起作用,框架自身会在domReady时进行一次扫描,通过ms-include加载子模板时,也会对当前模板进行一次扫描。 如果用户的页面是自己AJAX加载回来,或自己对元素设置了ms-*绑定属性,或是自己用require等动态加载库,在它的回调里定义VM,请不要忘了执行avalon.scan() 如果能确定扫描的区域,那么最好也请传入一个元素节点,让其更快地执行.

    请保持数据的扁平化,不要设计包含多级子对象的大对象,如{a:{b:{g:7}},d:{e:{f:3}}}。因此将这个对象转换为VM后,它的内部结构将更加庞大,每一级都添加大量辅助函数与同名的访问器属性,特别吃内存;另,avalon对多级对象的深层监控还不完善,第四层就力不从心了。

    将一次性使用的属性转换不可监控的,具体做法是名字前面加$,或把名字放在同级的$skipArray数组中。

    请保存数据的完整性与一致性,比[{v:1},{v:2},{v:3},{}]就不是一个好的数据源,因为第四个与前三个明显不同。[1,null,2,3,4]也是如此。请从JAVA数组的角度来后,每个元素的类型与结构必须保持一致,这才保证页面循环渲染或更新时不会出问题。

    请确保VM只包含数据与事件回调。数据是指字符串,数字,布尔,简单结构的纯对象(如{},{a:1}),日期对象(new Date())。像正则,空值(null, undefined)就不要放进去。函数要作为事件回调才放进去,因此框架内部会对ms-on-*, ms-click, ms-mouseout等绑定进行处理,确保不会执行两次(parseExpr里面预先检测动态生成的求值问题是否有错) ,什么AJAX请求也请放在事件回调中。不相关的函数请定义在define方法外,然后在事件回调里面调用。定义时,数据聚集在VM的上方,事件回调放在VM的下方

    请严格区分定义用的vm与define方法的返回值VM。define方法的参数是一个回调函数,这个函数也有一个参数,我在众多示例中,都命名为vm(就像angular的CTRL工厂方法,里面那个对象永远命名为$scope, 不同的是 我的不是强制性的),它是用于定义数据源应该包含什么数据与回调函数。 那只是一个普通的对象。而作为返回值的VM是一个成品, 已经添加大量辅助方法与覆盖上同名的访问器属性。在回调函数里,我们想引用外面的属性, 请vm将改成VM(这个也不是强制性的)。总而言之,记住vm只是用于定义,VM用于调用就行了。

    一个ms-controller只能应用于一个元素上。

    尽量使用ms-repeat而不是ms-repeat-xxx。

    关于网速慢,{{}}插值表达式暴露出来的问题, 我们可以定义这样一个样式规则进行处理[ms-controller],[ms-important]{display:none} 为有点类于angularjs的ng-cloak指令,在扫描之前起着羞丑布的作用。对于IE6不支持属性选择器的问题,请添加ms-controller, ms-important类名。

    .ms-controller, .ms-important{visibility:hidden}
    

    框架对应的实现如下:

        function scanTag(elem, vmodels, node) {
            //扫描顺序  ms-skip(0) --> ms-important(1) --> ms-controller(2) --> ms-if(10) --> ms-repeat(100) 
            //--> ms-if-loop(110) --> ms-attr(970) ...--> ms-each(1400)-->ms-with(1500)--〉ms-duplex(2000)垫后
            var a = elem.getAttribute(prefix + "skip")
            var b = elem.getAttributeNode(prefix + "important")
            var c = elem.getAttributeNode(prefix + "controller")
            if (typeof a === "string") {
                return
            } else if (node = b || c) {
                var newVmodel = VMODELS[node.value]
                if (!newVmodel) {
                    return
                }
                if (elem.msLoopData) {
                    delete VMODELS[node.value]
                }
                //ms-important不包含父VM,ms-controller相反
                vmodels = node === b ? [newVmodel] : [newVmodel].concat(vmodels)
                elem.removeAttribute(node.name) //removeAttributeNode不会刷新[ms-controller]样式规则
                avalon(elem).removeClass(node.name)//处理IE6
            }
            scanAttr(elem, vmodels) //扫描特性节点
        }
    

    清楚各种绑定在同一个元素的被扫描顺序,详见上面源码。

    使用ms-attr-prop=value代替ms-disabled, ms-enabled, ms-readonly, ms-checked, ms-checked

    利用好各种回调,如data-duplex-changed, data-with-sorted, data-include-loaded, data-include-rendered, data-each-rendered, data-repeat-rendered, data-with-rendered, data-widget-defined。

    朝圣之旅:入门教程--〉 官网教程 --〉GITHUB的示例--〉 组件编写指南

    最后的最后,最重要的最佳实践是请围绕VM编程而不是围绕DOM, avalon严格践行操作数据即操作DOM的理念,能让开发人员离开DOM都能轻松进行前端开发。JS中的VM处理业务逻辑与提供数据源,HTML中的绑定负责渲染与响应用户点击拖拽等行为,这样就最大保证了视图逻辑相分离。

  • 相关阅读:
    2020-2021-1 20209324 《Linux内核原理与分析》第八周作业
    2020-2021-1 20209324《Linux内核原理与分析》第七周作业
    2019-2020-1 20209324《Linux内核原理与分析》第六周作业
    2020-2021-1 20209324《Linux内核原理与分析》第五周作业
    2019-2020-1 20209324《Linux内核原理与分析》第四周作业
    2019-2020-1 20209324《Linux内核原理与分析》第三周作业
    2019-2020-1 20209324《Linux内核原理与分析》第二周作业
    T-Sql 递归查询
    JS浏览器兼容问题
    IE && FireFox在javascript上的区别
  • 原文地址:https://www.cnblogs.com/rubylouvre/p/3385373.html
Copyright © 2020-2023  润新知