由于JavaScript本身并不支持面向对象,但是我们可以利用其Prototype去模拟部分面向对象的语言特征。我们这儿要说的虚拟面向对象就是指Dorado7中提供的JavaScript模拟面向对象的编程技术。
在基础教程中我们只介绍Dorado JS对象的使用和相关约定,而忽略对象的声明、扩展等内容。
虚拟属性
我们使用Dorado提供的JSDOC的时候注意到,其中Dorado的JS对象通常都包含很多的attributes,如我们访问URL: http://www.bsdn.org/projects/dorado7/deploy/jsdoc/
访问dorado.widget下的Button控件:
这些attributes就是Dorado7对象的虚拟属性,之所以称它们为虚拟属性是,因为它们与Java中的属性不同的地方在于,Java中的属性我们都可以通过专用的getXXX/setXXX方法进行读取操作,但是Dorado7对象的虚拟属性我们需要通过如下的方式:
var v = editor.get("value"); button.set("caption", "OK");
也就是说当我们看到JSDOC中某一个Dorado控件具有的某些attributes,我们就可以通过get/set方法,例如刚才我们看到的Button中有icon属性,则我们就可以通过如下的方式设置其icon属性:
button.set("icon", "images/button_ok.gif");
下面介绍虚拟属性的一些其他特色:
set方法支持批量属性设置
如下代码,我们对一个对象的多个属性进行赋值操作:
button.set("icon", "images/ok.gif"); button.set("caption", "OK"); button.onClick = function(){ alert("You clicked OK."); }
这种代码有些罗嗦,尤其在属性较多情况下更是如此,有什么简化的办法呢?
虚拟属性的set方法支持属性批量设置,如下:
button.set({ icon: "images/ok.gif", caption: "OK", onClick: function() { alert("You clicked OK."); } });
通过这种赋值方式可以大大的简化代码的书写。
迭代式操作
通过前面的学习我们知道JSON可以构造一个很复杂的树结构的对象,Dorado对象在很多情况下也是树形结构,例如有一个oop为一个Dorado虚拟对象,其中含address虚拟属性,而address本身又是一个Dorado虚拟属性,我们希望取出其中的postCode,如果我们要存取postCode的值,可能的代码有:
oop.get("address").get("postCode"); oop.get("address").set("postCode", "7232-00124");
但是利用虚拟属性的功能,我们可以这么些代码:
oop.get("address.postCode"); oop.set("address.postCode", "7232-00124");
这样看起来代码是不是简洁多了,也很容易的就能读懂代码。对于迭代式get和set方法,还提供了一个更有意义的功能,即加入在迭代过程中遇到的不是一个Dorado的虚拟对象,而是一个标准的JSON对象,则这种迭代操作的处理机制依然有效。
事件
事件
Dorado为虚拟对象增加了很多事件,这些事件与通常Dom的事件并不一样,是Dorado为虚拟对象专门增加的事件,事件的添加方法:
方法一
button1.addListener("onClick", function(self) { //此方法可以为一个事件添加多个监听函数 });
这是Dorado中内部采用的添加事件的方法。
方法二
button1.set("onClick", function(self) { // 此方法只能定义一个监听函数 });
这儿要提一下虚拟属性的功能,前面我们介绍过虚拟属性,通过前面的学习上述代码的意图就是设置button1的onClick属性,由于不存在实际的onClick属性,且属性的值我们给了一个function,则Dorado事件引擎会自动的调用button1.addListener处理机制,将这个function注册到事件管理器中。推荐使用第二种方法,代码更为直接,他们之间的差别在于虚拟属性设置方法只能定义一个监听函数,而addListener可以添加多个function。
下面说明事件的几个公用特性,这些特性并不是每一个事件都有,但是这些特性是虚拟对象的事件的基本特性:
self和arg
Dorado7中所有的事件都支持self和arg参数,其中self表示激发事件的自身,如Button激活onClick事件,则self表示Button自身,如Editor激活onClick事件,则self表示Editor对象自身,arg的类型与具体事件类型有关,很多情况下都是一个JSON对象,其中可能包含有非常丰富的传入信息。不同的事件中arg的JSON对象的属性是不一样的,事件A可能arg中含有prop1,prop2,我们可以通过如下代码获取其属性:
var v1 = arg.prop1; var v2 = arg.prop2;
而事件B中可能传入的信息就是prop3,prop4,则代码就可能为:
var v3 = arg.prop3; var v4 = arg.prop4;
不同事件的arg的差别,要通过JSDOC查看,例如我们看Button控件:
http://bsdn.org/projects/dorado7/deploy/jsdoc/
其中的onClick事件:
注意其中arg的button,event和returnValue的说明
而其onRefreshDom事件的arg参数就为:
上面两张截图中onClick与onRefreshDom的事件中的arg参数是不一样的。
this
如实做AJAX范例中,按钮Ajax Multiply的onClick事件代码中我们接触到this的写法,但是我们未细讲这个this的含义:
var action = this.get("#multiplyAction"); dorado.MessageBox.prompt("Please input two numbers here", { defaultText: "3,5", callback: function(text) { var nums = text.split(","); var parameter = { num1: nums[0], num2: nums[1] }; action.set("parameter", parameter).execute(function(result) { dorado.MessageBox.alert(nums[0] + " * " + nums[1] + " = " + result); }); } });
其实这个this指的就是按钮所在的视图View:
几乎所有事件中的this均指向的是该控件隶属的View对象,View对象的onCreate事件中的this是指向其自身的。
onCreate事件中的this是个例外,因为控件总是先被创建然后才被添加到控件树上,因此在onCreate事件被触发时控件并不知道其隶属的View对象。所以onCreate事件中的this并不指向最终的View。而是指自身。
逻辑返回值
Dorado中对象某一个事件可以定义多个Listener的时候,这些Listener会按顺序依次触发,如果我们希望在第一个事件触发的过程中,屏蔽后面Listener的触发,则我们需要在第一个Listener中明确的返回一个false。这样后面的事件就会被跳过,不再执行。
processDefault
employeeDataType.addListener("beforeRemove", function(self, arg) { if (arg.entity.get("married")) { dorado.MessageBox.alert("已婚的员工不能被删除!"); arg.processDefault = false; } });
employeeDataType.addListener("beforeRemove", function(self, arg) { if (arg.entity.get("married")) { throw new dorado.Exception("已婚的员工不能被删除!"); } });
Attachments:
ButtonOnClick.png (image/png)
ButtonOnRefreshDom.png (image/png)
AjaxView.png (image/png)