迷你MVVM框架 avalonjs 學習教程四、數據填充

MVVM是前端的究極解決方案,大家可能用過jQuery,但那個寫的代碼不易維護;大家能夠聽過說requirejs與seajs,傳說中的模塊開發,加載器,但它們的最終目標是打包;大家可能聽過underscope,那是一個工具集;大家能夠據說過ejs,Mustache、HandlebarsJS等模板引擎,它們是用來替代字符串拼接……凡此種種,它們在咱們的業務開發中只是不多的部分,帶來的幫助也頗有限。前端開發,貫徹始終的是如何將後端的數據顯示出來,將用戶的輸入格式化送到後端,都離不開DOM操做,而DOM操做正是許多新手或從後端過來的人所懼怕。相比於JS的那點語法,DOM是最龐雜的,三次瀏覽器大戰留下的遺患至今沒有消彌,處處是地雷,所以咱們怎麼放心讓新人去趟這禍水呢。jQuery爲開發者發一個水泡,讓大家淹不死。但最佳方式,就是把這些腐敗沼澤都填了。avalon作到了,純數據操做的時代到來了。javascript

前三節就分別介紹了做用域,ViewModel,綁定屬性什麼的,它們是咱們的主角。其中ViewModel是咱們操做的主體,綁定屬性是讓咱們脫離DOM操做的關鍵。全部對ViewModel的操做,最終交由綁定屬性實現各類DOM功能。DOM功能是一個很範的概念,好比添加刪除類名,移除節點,讓某個元素看不見,爲元素添加某個屬性或某個事件……今天咱們介紹的就是最經常使用數據填充功能,讓後端的數據在頁面展現出來。MVVM是如此強大,估計今明年,大家會愈來愈頻繁地看到有關前端MVVM的主題分題,PPT。做爲一個簡單的示例,它們務必包含數據填充功能的展現。css

數據填充是avalon最簡單的功能,將數據打印到頁面上。這是全部後端模板最基本的功能,而後加上each, if, include等語法,實現更精細的制定。avalon經過綁定屬性,其實將整個頁面變成一個動態模板(詳看這裏)。將數據輸出到頁面涉及到如下指令。html

  • {{prop}}
  • {{prop|html}}
  • ms-text
  • ms-html
  • ms-value
  • ms-duplex

{{prop}}是最簡單實用的指令,什麼helloworld用它作最適合了。前端

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
        <script src="avalon.js"></script>
        <script>
            avalon.define({
                $id: "test",
                word: "Hello Avalon"
            })
        </script>
    </head>
    <body>
        <div ms-controller="test">
            <h1>{{word}}!!!!!</h1>
        </div>
    </body>
</html>

enter image description here

{{prop | html}}實際上是加一個過濾器,也只有文本節點中的插值表達式能夠加各類過濾器實現各類功能。html過濾器就是將此字符串轉換HTML節點再插入當前位置。不過這個{{prop|html}},框架是對它開了小竈,容許它原本就是一個元素節點或NodeList。java

ms-text與ms-html其實就是{{prop}}、{{prop|html}}的真身,框架內部都是走同一處理函數。不過ms-text、 ms-html做爲一個綁定屬性,必須附於元素節點之上,所以沒有前者那麼方便。git


<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
        <script src="avalon.js"></script>
        <script>
            avalon.define("test", function(vm) {
                vm.text = "<b> 1111  </b>"
            })
        </script>
    </head>
    <body>
        <div ms-controller="test">
            <div><em>用於測試是否被測除</em>xxxx{{text}}yyyy</div>
            <div><em>用於測試是否被測除</em>xxxx{{text|html}}yyyy</div>
            <div ms-text="text"><em>用於測試是否被測除</em>xxxx yyyy</div>
            <div ms-html="text"><em>用於測試是否被測除</em>xxxx yyyy</div>
        </div>
    </body>
</html>

enter image description here

此外,咱們還能夠經過config方法,更改插值表達式的界定符,由於{{}}可能被其餘框架的模板所佔用。建議界定符的長度大於1,不要設置爲>>這樣的位操做符。好比在DOMReady以前,咱們調用以下語句:angularjs

avalon.config({
   interpolate: ["<%", "%>"] //  要求openTag 不等於closeTag就能配置成功
})

enter image description here

像上面那樣,因爲網速慢把插值表達式暴露出來的問題, 咱們能夠定義這樣一個樣式規則進行處理,這有點類於angularjs的ng-cloak指令,在掃描以前起着羞醜布的做用。當掃描事後,框架會去掉綁定屬性,及ms-controller、ms-important這兩個類名,它們就顯示出來了。github

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

上述四種指令是用在文本節點上,但數據還能經過表單元素的value值顯示出來,因而有了ms-value指令。ms-value爲了應對複雜的顯示,也支持插值表達式,但裏面不能使用過濾器。後端

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
        <script src="avalon.js"></script>
        <script>
            avalon.define({
                $id: "test",
                text: "<b> 1111  </b>"
            })
        </script>
    </head>
    <body>
        <div ms-controller="test">
            <input ms-value="text"/>
            <textarea ms-value="xxxxxxxx{{text+'!!'}}yyyyyyyy"/></textarea>
        </div>
    </body>
</html>

enter image description here

上面的功能,後端模板與前端模板也能作到,但ms-duplex就逆天了。它是avalon實現雙向綁定的一個重要綁定。雙向綁定通俗說,當咱們修改ViewModel的屬性,經過Object.defineProperty重寫屬性的setter,getter同步視圖,而在視圖上偷偷綁定一些input、click、change事件,將元素的value同步到ViewModel上。ms-duplex就是這樣幹,也意味着它只對表單元素生效。avalon爲文本域,文本區,密碼域這三個控件綁定了input事件,換言之,用戶每改一個字符都會當即發生同步,固然用戶能夠在元素定義data-duplex-event=」change」屬性,就能夠改爲change事件。對於單選框,複選框,下拉條是綁定了change事件。數組

在IE6-8下,沒有input事件,avalon使用onpropertychange事件,單選框複選框的change事件有BUG,改用click事件,總而言之,avalon設法讓舊式IE與W3C瀏覽器保持一致。

若是用戶想在內容發生改變後執行某一回調,avalon也提供了data-duplex-changed回調。此外,用戶也能夠在VM上使用$watch回調進校訂。所以,有了ms-duplex作數據驗證是很是簡單的。

咱們還能夠在元素節點上定義data-duplex-observe=」false」來禁止雙向同步。

ms-duplex還能夠接第三個參數,總括起來,它們的語法以下:

ms-duplex=」prop」 當元素爲text, password, textarea時,要求prop爲一個字符串,當咱們改動它的內容時,avalon就會將此元素的value值賦給prop(在默認狀況下,是使用input事件進行綁定,即每改動一個字符,都會進行同步,你們也能夠指定data-duplex-event="change",改用change事件進行綁定) 當元素爲radio時,要求prop爲一個布爾, 當咱們改動它的內容時,avalon就會將此元素的checked值(布爾)賦給prop 當元素爲checkbox時,要求prop爲一個數組, 當咱們改動它的內容時,avalon就會將此元素的value值push進prop 當元素爲select時,要求prop爲一個字符串或數組(視multiple的值), 當咱們選中它的某一個項時,avalon就會將此option元素的value值或text值(沒有value時)push進prop。

ms-duplex-text=」prop」 只能用於radio,用於模擬text控件的行爲, 要求prop爲一個字符串,當咱們選中某一個radio時,avalon就會將此元素的value值賦給prop 用於實現多選一。

ms-duplex-radio=」prop」 只能用於checkbox,用於模擬radio控件的行爲, 要求prop爲一個布爾,當咱們選中某一個checkbox時,avalon就會將此元素的checked值(布爾)賦給prop 多用於實現GRID中的全選/全不選功能

ms-duplex-bool=」prop」 只能用於radio, 要求prop爲一個布爾,而且元素的value爲「true」或「false」,當咱們選中某一個radio時,avalon就會將此元素的value轉換爲布爾,賦給對應的prop。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <script src="avalon.js"></script>
        <script>
            avalon.define({
                $id: "test",
                aaa: {
                    xxx: "444",
                    yyy: "555"
                },
                bbb: "yyy",
                zzz: "text"
            })
        </script>
    </head>
    <body ms-controller="test">
        <input ms-duplex="aaa['xxx']"><br/>
        <input ms-duplex="aaa[bbb]"><br/>
        <input ms-duplex="zzz" ms-data-duplex-observe="zzz"/>當這裏的值變成false,就會禁止雙向同步
        <p>{{aaa.xxx}}</p>
        <p>{{aaa.yyy}}</p>
        <p>{{zzz}}</p>
    </body>
</html>

enter image description here

這裏有更多ms-duplex的例子。弄懂它們就能夠處理大多數表單需求了,而後你就會以爲生活變美好了一些。這快感正如咱們一開始從原生JS轉到jQuery的那樣。時代老是在進步的,早期瞭解MVVM,早期擺脫DOM的桎梏!

相關文章
相關標籤/搜索