avalon你們可能不熟悉,可是Knockout估計或多或少聽過用過,那麼說說KO的幾個概念css
本章主要提到 監控屬性 與 依賴跟蹤(後更名叫計算屬性)git
監控顧名思義,監聽着你設定目標的變化,換句話說可以通知訂閱者它的改變以及自動探測到相關的依賴。github
計算屬性,就是依賴監控屬性變化而自動調用處理更新數組
KO的一個例子ruby
若是你已經有了監控屬性firstName和lastName,你想顯示全稱怎麼辦? 這就須要用到依賴監控屬性了 – 這些函數是一個或多個監控屬性, 若是他們的依賴對象改變,他們會自動跟着改變。mvvm
例如,下面的view model,函數
var viewModel = { firstName: ko.observable('Bob'), lastName: ko.observable('Smith') };
… 你能夠添加一個依賴監控屬性來返回姓名全稱:this
viewModel.fullName = ko.dependentObservable(function () { return this.firstName() + " " + this.lastName(); }, viewModel);
而且綁定到UI的元素上,例如:編碼
The name is <span data-bind="text: fullName"></span>
… 無論firstName仍是lastName改變,全稱fullName都會自動更新(無論誰改變,執行函數都會調用一次,無論改變成什麼,他的值都會更新到UI或者其餘依賴監控屬性上)spa
OK
KO是怎麼實現雙向機制的呢?
avalon實現雙向綁定跟ko的實現其實大同小異,可是ko的實現異常的複雜,avalon則清晰不少
上列子,而後分析
HTML結構
<div id='box' ms-controller="box"> <div style=" background: #a9ea00;" ms-css-width="w" ms-css-height="h" ms-click="click"></div> <p>{{ w }} x {{ h }}</p> <p>W: <input type="text" ms-model="w" data-event="change"/></p> <p>H: <input type="text" ms-model="h" /></p> </div>
JS
avalon.define("box", function(vm) { vm.w = 100; vm.h = 100; vm.click = function() { vm.w = parseFloat(vm.w) + 10; vm.h = parseFloat(vm.h) + 10; } }) avalon.scan(document.getElementById('box')
就是官網提供的一個DEMO http://rubylouvre.github.io/mvvm/、
分析HTML結構:
JS處理中:
view model視圖模型的構建在之前已經講過了,這裏主要講下雙向綁定的構建及處理的原理
1.構建VM的時候,對監控屬性進程轉化處理,生成一個監控對象
監控對象是經過Object.defineProperty轉換過的處理函數,因此在setter,getter時候會調用轉化的處理函數,這個用戶是不可見的
賦值時處理 setter
var old = value; if (valueType === "array" || valueType === "object") { //監控數組 if (value && value.$id) { updateViewModel(value, neo, Array.isArray(neo)) } else if (Array.isArray(neo)) { value = Collection(neo) value._add(neo) } else { value = modelFactory(neo, neo) } } else { value = neo } accessor.value = value; model[name] = value && value.$id ? value.$model : value; //值變化了,通知頂層改變 notifySubscribers(accessor); vmodel.$fire && vmodel.$fire(name, value, old)
取值時處理 getter
collectSubscribers(accessor); //收集視圖函數 return value
操做時
vm.w = 100 setter,就會默認調用賦值處理函數
vm.w 一樣,getter 調用取值函數
這樣方式,比ko的this.firstName() + " " + this.lastName(); 友愛多了,由於KO轉換的是處理函數,必需要函數調用。。。別提多變扭
關鍵點:
collectSubscribers //收集視圖函數
notifySubscribers //值變化了,通知頂層改變
這個2個方法,用來處理依賴關係的
實現的流程:
預處理過程:
交互時:
畫了張圖。。
本文只是很簡單的說了下監控屬性大概的邏輯,還有計算屬性的處理,轉化,調用,以後會分解