avalon最佳實踐

最近從angular的QQ羣與新浪微博拉了許多人來用個人avalon,成爲第一批登上方舟,脫離DOM苦海的人。短短三個月內,5羣的朋友也搞出幾個切實實行的案例了。爲應對粉絲們高益高漲的熱情,遂放出此文章。css

avalon的數據綁定須要通過掃描才能起做用,框架自身會在domReady時進行一次掃描,經過ms-include加載子模板時,也會對當前模板進行一次掃描。 若是用戶的頁面是本身AJAX加載回來,或本身對元素設置了ms-*綁定屬性,或是本身用require等動態加載庫,在它的回調裏定義VM,請不要忘了執行avalon.scan() 若是能肯定掃描的區域,那麼最好也請傳入一個元素節點,讓其更快地執行.html

請保持數據的扁平化,不要設計包含多級子對象的大對象,如{a:{b:{g:7}},d:{e:{f:3}}}。所以將這個對象轉換爲VM後,它的內部結構將更加龐大,每一級都添加大量輔助函數與同名的訪問器屬性,特別吃內存;另,avalon對多級對象的深層監控還不完善,第四層就力不從心了。前端

將一次性使用的屬性轉換不可監控的,具體作法是名字前面加$,或把名字放在同級的$skipArray數組中。node

請保存數據的完整性與一致性,比[{v:1},{v:2},{v:3},{}]就不是一個好的數據源,由於第四個與前三個明顯不一樣。[1,null,2,3,4]也是如此。請從JAVA數組的角度來後,每一個元素的類型與結構必須保持一致,這才保證頁面循環渲染或更新時不會出問題。git

請確保VM只包含數據與事件回調。數據是指字符串,數字,布爾,簡單結構的純對象(如{},{a:1}),日期對象(new Date())。像正則,空值(null, undefined)就不要放進去。函數要做爲事件回調才放進去,所以框架內部會對ms-on-*, ms-click, ms-mouseout等綁定進行處理,確保不會執行兩次(parseExpr裏面預先檢測動態生成的求值問題是否有錯) ,什麼AJAX請求也請放在事件回調中。不相關的函數請定義在define方法外,而後在事件回調裏面調用。定義時,數據彙集在VM的上方,事件回調放在VM的下方 angularjs

請嚴格區分定義用的vm與define方法的返回值VM。define方法的參數是一個回調函數,這個函數也有一個參數,我在衆多示例中,都命名爲vm(就像angular的CTRL工廠方法,裏面那個對象永遠命名爲$scope, 不一樣的是 個人不是強制性的),它是用於定義數據源應該包含什麼數據與回調函數。 那只是一個普通的對象。而做爲返回值的VM是一個成品, 已經添加大量輔助方法與覆蓋上同名的訪問器屬性。在回調函數裏,咱們想引用外面的屬性, 請vm將改爲VM(這個也不是強制性的)。總而言之,記住vm只是用於定義,VM用於調用就好了。github

一個ms-controller只能應用於一個元素上。編程

儘可能使用ms-repeat而不是ms-repeat-xxx。數組

關於網速慢,{{}}插值表達式暴露出來的問題, 咱們能夠定義這樣一個樣式規則進行處理[ms-controller],[ms-important]{display:none} 爲有點類於angularjs的ng-cloak指令,在掃描以前起着羞醜布的做用。對於IE6不支持屬性選擇器的問題,請添加ms-controller, ms-important類名。ruby

.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中的綁定負責渲染與響應用戶點擊拖拽等行爲,這樣就最大保證了視圖邏輯相分離。

相關文章
相關標籤/搜索