avalon的雙向綁定機制,是通過一條依賴鏈實現。此依賴鏈最底層是監控屬性、監控數組,中層是計算屬性、監控函數,再上點是求值函數,最上層是視圖刷新函數。

所謂計算屬性,監控屬性,監控函數屬性,我們改變它們的值,它們會引發視圖變化;而監控數組,是我們調用它的一些方法,也會引發視圖變化。
var vm = avalon.define({
a: "這是監控屬性",
$b: "這是非監控屬性",
$skipArray: ["c", "d"],
c: "位於$skipArray里,因此也是非監控屬性",
d: "位於$skipArray里,因此也是非監控屬性",
obj: {//這個obj是一個子VM
xx: "xxx"
},
fn: function() {
alert(1)//這里面沒有vm的監控屬性(僅指其第一層屬性),因此是一個普通函數
},
fn2: function() {
return vm.a //這里面有vm的監控屬性(僅指其第一層屬性),因此是一個監控函數
},
fn3: function() {
return vm.fn2()//fn2是方法而不是監控屬性,因此也是一個普通函數
},
array: [1, 2, 3], //這是一個監控數組
computed: {//這是一個計算屬性,因此它有一個get方法,this指向vm
get: function() {
return this.a + this.$b
}
},
computed2: {//這是一個計算屬性,因此它有get,set方法
get: function() {
return this.a + "!!!"
},
set: function(v) {
this.a = v
}
},
ccc: {//這一個普通的對象,構成一個子VM,因為計算屬性只允許最多有兩個方法,不能出現第三個屬性
get: function() {
return this.a + "!!!"
},
set: function(v) {
this.a = v
},
host: {}
}
})
為了性能起見,我們需要將一些屬性變成不可監控。這有兩個途徑,在屬性名或方法名前加一個$,或者把屬性名放到$skipArray數組里。
監控屬性,計算屬性,監控屬性什么都是位於VM中;而最上面兩層是位於視圖,通過分解綁定屬性,推斷出來。比如說ms-text=”aaa”,我們從屬性名得到其視圖刷新函數(所有視圖刷新函數都定義在 avalon.bindingExecutors對象上),求值函數是通過內部的parseExpr方法編譯出來。
<!DOCTYPE html>
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<script src="avalon.js" type="text/javascript"></script>
<script>
vmodel = avalon.define({
$id: "test",
a: 1,
b: 2,
fn: function() {
return (parseFloat(vmodel.a) || 0) + (parseFloat(vmodel.b) || 0)
}
})
</script>
</head>
<body ms-controller="test">
<div><input ms-duplex="a"/>{{a}}</div>
<div><input ms-duplex="b"/>{{b}}</div>
<div>{{fn()}}</div>
</body>
</html>

<!DOCTYPE html>
<html>
<head>
<title>ms-class</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script src="avalon.js"></script>
<style>
.green{
background: green;
}
</style>
<script type="text/javascript">
var model = avalon.define({
$id: "test",
array: [],
add: function(){
model.array.push(1)
},
remove: function(){
model.array.pop()
}
})
</script>
</head>
<body ms-controller="test" >
<div ms-class="green: array.length" style="width:400px;height:200px">
<button ms-click="add" type="button">add</button><button ms-click="remove" type="button">remove</button>
</div>
</body>
</html>
一般情況下,都是上層依賴下層,下層發生改變,就會自動向上冒泡,到視圖刷新函數這一層,實現視圖的改變,只有一個例外,就是ms-duplex。它會偷偷 在視圖上綁定一些事件,通過監聽表單元素的值,將它直接同步到下方的監控屬性與計算屬性。
