迷你簡單易用的MVVM框架
avalon的介紹 http://rubylouvre.github.io/mvvm/
按照作者的介紹,在HTML中添加綁定,在JS中用avalon.define定義ViewModel,再調用avalon.scan方法,它就能動了!
神奇的代碼:
如上圖所示:
開發者:
1 定義一個帶有自定義標簽的HTML結構
2 定義一個簡單的JS代碼
用戶操作:
用戶在input文本框中改變值時,你就會發現對應的多條相關聯的記錄都被同步修改
問題:
- 事件是什么時候綁定的,因為開發者都沒有操作dom
- js代碼中定義的值,如何關聯到html代碼中
- html代碼中如何實現自動同步視圖(input輸入更改一條記錄,多條相關聯的同步被修正)
帶着這幾個問題,我們一起走入avalon源碼部分
首先對於MVVM模式,我們理解幾個概念:
- M,模型,一個數據體,用於填允我們的頁面,通常PHP交給我們時數據已經填好了,想改變,就要再發出請求,然后通過jQuery尋找節點,修改它的innHTML與innerText。當然DOM操作是非常繁鎖的,什么透明度,背景,位置等CSS屬性我們都需要通過操作類名來修改。我們有時忙乎於這些細節,而把我們業務混在其中了。因此調試時,業務好了,但樣式壞了,樣好修好,這時務業又爆開了……
- 在MVVM中,M只是一個過客,它與其他表示業務狀態的東西融入VM(ViewModel)中。ViewModel是一個狀態的集合,當然還拖家帶口監控着大量的回調。狀態聽起來是個深奧的概念,其實就是一個開關。比如if(aaa){}語句中的aaa,就是表示true與false,switch(bbb){}語句,它表示有多個值的狀態,就像有人幼年,童年,少年,青年,中年,老年這幾個階段,它們都指向同一個東西。
- 在MVVM中,數據是核心。而jQuery則以DOM為核心。而DOM只是HTML在JS的世界的抽象,是一個很易變的東西。因此如果業務代碼遍歷選擇器表達式會非常難維護。但不可否認,jQuery是操作DOM的王者,讓我們操作DOM順手拈來。但如果不讓你操作DOM,不是更好嗎?就像jQuery不讓你用getElementById,getElementsByTagName, querySelecterAll,大家都不知道里面有多少坑,短短幾個字母$(expr)是背后sizzle選擇器引擎1700行的實現!!!!jQuery其實是在用戶代碼與原生API中提供一層厚厚的粘合層,因此摸起來光溜溜。在MVVM中,DOM操作基本是水下運作了。由於VM與V之間的雙向綁定,操作了VM中的數據(當然只能是監控屬性),就會同步到DOM,我們透過DOM事件監控用戶對DOM的改動,也會同步到VM。DOM隱形了,就像軟件公司,到處跑出來活動的是業務員與不寫代碼的經理老總,程序員全部關起來加班!雖然這比喻有點殘酷,但這正體現了各司其職的威力。能說會道去拉風投接單子沒什么不妥,喜歡呆在電腦前的就讓他呆吧。jQuery的世界就是一個混亂的公司,全能的程序員什么都做
- 為了各司其職,必須有良好的分層。MVVM划分三層,M,VM,V,M是原始數據,用於轉換為VM,VM管理狀態與綁定回調,V通過綁定得到VM的狀態與回調,渲染頁面,綁定事件,切換類名,什么臟活都攬了——但用戶只需要聲明
avalon與其他前端MVVM框架最大的不同是:
- VM是用ecma262v5的新API, Object.defineProperties生成的一個充滿訪問器的對象,這樣的對象,能通過用戶對它的屬性的讀寫,觸發定義時的getter, setter函數。getter, setter對rubyer, pythoner, C#er應該很熟悉,我就不展開了。舊式IE,avalon利用VBScript的類實例,它也存在其他語言的訪問器。不過,VBS對象不像JS對象那樣隨意添加新屬性,刪除已有屬性,因此我們就無法監后添加的新屬性。Object.defineProperties也一樣,它能處理的屬性也只是它定義時的屬性,想監控后來的,需要再調用一次Object.defineProperties。盡管如此,也比其他MVVM框架魔幻多了
@author Aaron