轻量级前端MVVM框架avalon - 模型转换
生活随笔
收集整理的這篇文章主要介紹了
轻量级前端MVVM框架avalon - 模型转换
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
接上一章 ViewModel
?
modelFactory工廠是如何加工用戶定義的VM?
附源碼
- 洋洋灑灑100多行內部是魔幻般的實現
- VM是用ecma262v5的新API, Object.defineProperties生成的一個充滿訪問器的對象,這樣的對象,能通過用戶對它的屬性的讀寫,觸發定義時的getter, setter函數。getter, setter對rubyer, pythoner, C#er應該很熟悉,我就不展開了。
- 舊式IE,avalon利用VBScript的類實例,它也存在其他語言的訪問器。不過,VBS對象不像JS對象那樣隨意添加新屬性,刪除已有屬性,因此我們就無法監后添加的新屬性。Object.defineProperties也一樣,它能處理的屬性也只是它定義時的屬性,想監控后來的,需要再調用一次Object.defineProperties。
?
整個工廠方法內部都是圍繞著scope處理
skipArray //要忽略監控的屬性名列表
0: "$json" 1: "$skipArray" 2: "$watch" 3: "$unwatch" 4: "$fire" 5: "$events"?
我們還是已官網的demo為列
avalon.define("simple", function(vm) {vm.firstName = "司徒"vm.lastName = "正美"vm.fullName = {//一個包含set或get的對象會被當成PropertyDescriptor,set: function(val) {//set, get里面的this不能改成vmvar array = (val || "").split(" ");this.firstName = array[0] || "";this.lastName = array[1] || "";},get: function() {return this.firstName + " " + this.lastName;}}})avalon.scan(document.querySelector("fieldset"));?
此時傳入的vm為
$watch: function noop() {firstName: "司徒"fullName: ObjectlastName: "正美"?
意圖很明顯就是遍歷這些屬性,給出相對應的處理,具體我們接著往下看
?????????? 純凈的js對象,所有訪問器與viewModel特有的方法屬性都去掉
1: if (!watchOne[name]) { 2: json[name] = value; 3: }幾個簡單的條件過濾:
1: //判斷類型 2: var valueType = avalon.type(value); 3: ? 4: if (valueType === "Function") { 5: // 第一個就是$watch" 被重復假如到列表了 6: VBPublics.push(name); //函數無需要轉換 7: } else {?
跳過過濾的條件后:
核心的轉換
- 轉換計算屬性
- 轉化監控屬性
?
轉換計算屬性:
判斷的條件,值類型是對象,并且有get方法,并且方法要少于等于2個
if (valueType === "Object" && typeof value.get === "function" && Object.keys(value).length <= 2) {滿足條件的
vm.fullName = {//一個包含set或get的對象會被當成PropertyDescriptor,set: function(val) {//set, get里面的this不能改成vmvar array = (val || "").split(" ");this.firstName = array[0] || "";this.lastName = array[1] || "";},get: function() {return this.firstName + " " + this.lastName;}}具體有什么用我們接著往下看
?
轉化監控屬性
?
?
accessor[subscribers] = [];- 別看這個代碼是空的函數,不起眼,雙向綁定就是看他了,我們先Mark下
//生成defineProperties需要的配置屬性Descriptions[name] = {set: accessor,get: accessor,enumerable: true};
- Descriptions臨時對象? //收集內部用于轉換的對象
- enumerable 很重要,為false的話 ,for in就找不到它了
這樣循環后就把該干嘛的不該干嘛的都給區分開了
最后都保存在Descriptions中
此時的Descriptions
1: Descriptions: Object 2: ? 3: firstName: Object 4: enumerable: true 5: get: function (neo) { //創建監控屬性或數組 6: set: function (neo) { //創建監控屬性或數組 7: ? 8: fullName: Object 9: enumerable: true 10: get: function (neo) { //創建計算屬性 11: set: function (neo) { //創建計算屬性 12: ? 13: lastName: Object 14: enumerable: true 15: get: function (neo) { //創建監控屬性或數組 16: set: function (neo) { //創建監控屬性或數組 ?看吧就是這樣給包裝了一下,只是定義了但是還沒生效
所以defineProperties(model, Descriptions); 給執行以下? (defineProperties的方法見前面)
?
model 就是工廠模式轉換后的新的vm模型對象了, 因為在開始遍歷scope的過濾了一些東東,原本也是用戶定義的,所以這時候我們還得加到新的vm-》model中去、
//添加用戶定義的未轉換的函數到模型VBPublics.forEach(function(name) {if (!watchOne[name]) {model[name] = scope[name];}});轉載于:https://www.cnblogs.com/aaronjs/p/3146848.html
總結
以上是生活随笔為你收集整理的轻量级前端MVVM框架avalon - 模型转换的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【原】数字图像处理学习之三彩色图像处理
- 下一篇: 熬之滴水穿石:JSP--HTML中的JA