avalon「操做數據即操做DOM」的能力,讓咱們能夠專致於業務,寫出更專業,更優雅,更易維護的代碼來。如今讓咱們看看如何實現一個序列號輸入功能。它的需求如下:html
先給出代碼:git
<!DOCTYPE html> <html> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script src="avalon.js"></script> <style> input:focus{ border: 1px solid #a9ea00; background:#f0f0f0; } </style> <script> var model = avalon.define("xxx", function(vm) { vm.seriesNumber = [{value: ""}, {value: ""}, {value: ""}, {value: ""}] vm.focusIndex = NaN //得到焦點,實現輸入框中的跳轉操做 vm.focus = function(a, b) { var el = this; if (a === avalon(el).data("index")) { setTimeout(function() { el.focus() el.select(); }, 0); } } vm._focus = function() { model.$unwatch() model.focusIndex = avalon(this).data("index") model.$watch() } //經過貼粘實現智能輸入 vm.paste = function(e) { var index = avalon(this).data("index") var text = "" if (e.clipboardData) { avalon.log("w3c") text = e.clipboardData.getData("text/plain"); } else if (window.clipboardData) { avalon.log("ie") text = clipboardData.getData("Text") } var array = text.match(/\w{4}/g) || [] for (var i = 0; i < array.length; i++) { var el = model.seriesNumber[index + i] if (el) { el.value = array[i] } } var last = Math.min(index + i, 3) setTimeout(function() { model.focusIndex = last }, 0) } }) //綁定$watch,實現輸入字數限制與智能跳轉 model.seriesNumber.forEach(function(el, index) { el.$watch("value", function(a, b) { if (a.length >= 4) { model.focusIndex = index + 1 //跳轉 el.value = a.slice(0, 4) } }) }) //剛開始時聚焦到第一個輸入框中 avalon.ready(function() { model.focusIndex = 0 }) </script> </head> <body> <div ms-controller="xxx" ms-each-el="seriesNumber"> <input ms-duplex="el.value" ms-on-paste="paste" ms-focus="_focus" ms-bind="focusIndex: focus" ms-data-index="$index"> </div> <h2>1234aaaabbbb6789</h2> </body> </html>
首先,咱們要監聽一個input裏面的內容變化,立刻能想到用ms-duplex,該綁定能逐字符地監聽變化。但因爲存在多個INPUT,爲了方便循環處理,咱們用到一個數組。但數組VM中只能監聽它的長度變化。所以整成對象數組,而後監聽這些對象的某個字符串屬性就好了。github
這個value值的變更,咱們能夠綁定$watch回調,當輸入值超過4個字符串時,進行跳轉操做。算法
el.$watch("value", function(a, b) { if (a.length >= 4) { model.focusIndex = index + 1 //跳轉 el.value = a.slice(0, 4) } })
若是實現跳轉操做呢,咱們使用另外一個新屬性focusIndex 來監聽,當它變化時,咱們再調用一個跳轉方法。而這個跳轉方法須要獲得元素節點。這惟有萬能綁定ms-bind 能幹這事。數組
ms-bind="vmProp:vmCallback"
vmCallback的this指向被綁定元素,並傳入此綁定屬性的先後兩個值。vmProp的值每次變更都會調用vmCallback。ruby
貼粘時,咱們須要用到paste事件,但avalon默認沒此綁定,須要用ms-on傳入事件名,這裏面作些兼容處理,逐一修改seriesNumber 數組對象的value 值就好了。mvvm
整個流程簡單利落,除了跳轉時咱們用到一些DOM方法,其餘都是對數據的操做。這與以往jQuery, Prototype.js, YUI的實現思路徹底不一樣。打個比喻,avalon帶來的技術體驗,如同書法與打印機的區別。jQuery好優雅,能讓你精確控制每一步DOM操做,DOM操做越是複雜,如同繁體字那樣縱橫捭闔,越是顯得jQuery遊刃有餘。avalon好乾淨,不要準備文房四寶,一張A4,一臺打印機就好了,刷刷地出來你要的東西,乾脆利落,沒什麼人情味,但效率奇高,是工業革命的先聲。從歷史的發展過程來看,書法這種講究技術,滲雜着許多人個品味地藝術被整齊劃一的印刷術逼到一死角,被剝奪了文化傳承者的角色。jQuery這些也同樣,DOM操做最快,也比不上MVVM這種印刷機般的技術,後者能不着痕跡地同步視圖,裏面精密的算法保證不會存在冗餘無用的DOM操做。前者還存在「糟糕的書法者」問題,最好的筆硯,在某些人手裏也是潦草不堪,看守打印機工做就沒這問題。從勢利的角度來看,就是怎麼可以給資本家帶來好處,怎麼在相對時間內可以有更多更快, 更穩定的產出,就怎麼快被採納,人性使然。ui
相關文章this