廢話說了大幾篇,咱們開始來點乾貨了~ html
定義一個ViemMode 程序員
<fieldset ms-controller="simple"> <legend>例子</legend> <p>First name: <input ms-model="firstName" /></p> <p>Last name: <input ms-model="lastName" /></p> <p>Hello, <input ms-model="fullName"></p> <div>{{firstName +" | "+ lastName }}</div> <p>nick name: <input ms-model="nick.name" /></p> <p>{{nick.name}}</p> </fieldset> avalon.define("simple", function(vm) { vm.firstName = "司徒" vm.lastName = "正美" vm.fullName = {//一個包含set或get的對象會被當成PropertyDescriptor, set: function(val) {//set, get裏面的this不能改爲vm var array = (val || "").split(" "); this.firstName = array[0] || ""; this.lastName = array[1] || ""; }, get: function() { returnthis.firstName + " " + this.lastName; } }, vm.nick = { name: "暗黑之民" } });
這是官方給出的DEMO,咱們看看對應的操做定義 數組
HTML中: 瀏覽器
Javascript中: app
由於在ViewModel的轉化中會用到defineProperty的定義,有必要先預先提出來 框架
要了解詳細,見個人一篇譯文 (譯)ECMAScript 5 Objects and Properties 函數
JavaScript中有三種不一樣類型的屬性:oop
命名數據屬性,就是咱們在IE8碰到的絕對大多數屬性,能夠隨意刪除添加,設置什麼返回什麼,不會在內部作多餘的事。 this
var obj = { prop: 123 }; console.log(obj.prop); // 123 console.log(obj["prop"]); // 123 obj.prop = "abc"; obj["prop"] = "abc";
var obj = {} var _a = 1; Object.defineProperty(obj, "a", { get: function() { return _a }, set: function(a) { _a = a + 10 } }); console.log(obj.a) //1; obj.a = 20; console.log(obj.a) //30;
走進vm的幕後: spa
源碼:
1 avalon.define = function(name, deps, factory) { 2 var args = [].slice.call(arguments); 3 if (typeof name !== "string") { 4 name = generateID(); 5 args.unshift(name); 6 } 7 if (!Array.isArray(args[1])) { 8 args.splice(1, 0, []); 9 } 10 deps = args[1]; 11 if (typeof args[2] !== "function") { 12 avalon.error("factory必須是函數"); 13 } 14 factory = args[2]; 15 var scope = { 16 $watch: noop 17 }; 18 deps.unshift(scope); 19 factory(scope); //獲得全部定義 20 var model = modelFactory(scope); //轉爲一個ViewModel 21 stopRepeatAssign = true; 22 deps[0] = model; 23 factory.apply(0, deps); //重置它的上下文 24 deps.shift(); 25 stopRepeatAssign = false; 26 model.$id = name; 27 return avalon.models[name] = model; 28 };
咱們一行行分析:
var scope = { $watch: noop };
factory(scope); //獲得全部定義
var model = modelFactory(scope); //
factory.apply(0, deps);
return avalon.models[name] = model;
很明顯轉化後的模型對象掛在到了全局中,方便在掃描節點綁定中獲取
因此整個VM的建立過程,
核心點就是
modelFactory方法了下篇繼續着中分析~