更新时间:2022-08-27 15:00:18
废话说了大几篇,我们开始来点干货了~
定义一个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中:
因为在ViewModel的转化中会用到defineProperty的定义,有必要先预先提出来
要了解详细,见我的一篇译文 (译)ECMAScript 5 Objects and Properties
JavaScript中有三种不同类型的属性:
命名数据属性,就是我们在IE8碰到的绝对大多数属性,可以随意删除添加,设置什么返回什么,不会在内部做多余的事。
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的幕后:
源码:
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方法了
本文转自艾伦 Aaron博客园博客,原文链接:http://www.cnblogs.com/aaronjs/p/3145392.html,如需转载请自行联系原作者