Qomo之快速上手
-----
我发现,无论是哪种成功的语言,总是有一个快速入门的读物,而无论它们本身是
如何的复杂、艰涩或难于理解。反过来,不成功的语言,总是带有一堆技术性十足、
充满了想象和预期的文档。后者的这些文档,有些甚至比代码还多,但是这同样未
能挽救它们的失败。
于是,我同样地看到了Qomo。我发现Qomo发布过的文档中,总是有大量无法让人理
解的东西。如果你准备写一门语言,那么可能Qomo的文档和代码会给你许多启发。
而如果你只是打算用它,那么大概会变得很痛苦。然而,如果一个人因为想写一门
语言而去了解Qomo,那么他大概不会再使用Qomo,这是因为各自存有不同的目标。
于是,我想Qomo小组应该为“一个普通的使用者”而写一些东西。例如现在这篇。
一、装载Qomo
-----
我们计划在将来为各种JavaScript应用环境加入一个定制的loader,用来装入Qomo
的其它部分。但现在,Qomo还主要是用在浏览器中。所以他的装载代码是这样:
- <scriptsrc="js/Qomo.js">script>
在这个示例中,我们假设你网站中的文件是按如下方式组织的:
- <your_site>\test.html
- <your_site>\js\Qomo.js
- <your_site>\js\Build\*.*
- <your_site>\js\Components\*.*
- <your_site>\js\Framework\*.*
- <your_site>\js\Qomo.js
二、创建一个类,及其实例
-----
Qomo主要扩展了一些面向对象的语法。最简单的用法,总是包括一个类注册的函
数。例如:
- //1.声明一个构造器
- functionMyObject(){
- //..
- }
- //2.类注册(创建这个类TMyObject)
- TMyObject=Class(TObject,'MyObject');
-
- //3.创建实例的两种(效果上是一样的)
- obj1=newMyObject();
- obj2=TMyObject.Create();
的第一个参数也可以TMyObject,或者其它任何的、Qomo识别的类。
三、如果你想为对象添加一些私有的属性(attributes)
-----
如果你想这样做,那么你找对了东西,Qomo天生就是这种“私有”和“稳藏”而
设计的。这在上面的代码中,修改一下构造器就可以做到:
- //构造器
- functionMyObject(){
- Attribute(this,'Name','MyObject','r');
- Attribute(this,'Size',100);
- }
- //类
- TMyObject=Class(TObject,'MyObject');
-
- //实例
- obj1=newMyObject();
- obj2=newMyObject();
-
- //两个实例的私有属性不同
- obj1.set('Size',20);
- alert(obj1.get('Size'));//20
- alert(obj2.get('Size'));//100
四、让Qomo在网页中变得更有用
-----
对于网页制作者来说,他们关心的只是网页中如何方便地使用Qomo,而并不是上面这些类、
子类如何创建。大多数情况下来说,的确如此。
而简单地说来,我们可能在关心在网页中如何存取一个页面上的东西,比如一个用ID标识
的对象。在Qomo中,这比较方便。
- <scriptsrc="js/Qomo.js">script>
-
- <body>
- <inputid="pwd"value="mypasswordinhere">
- body>
-
- <script>
- //(*注)
- //$import('Components/Components.js');
-
- el=THtmlController.Create('pwd');
- alert(el.get('value'));
- script>
(*注)在V2.1以前版本的Qomo缺省核心库中是不包括Components.js的。这种情况下需要使
用$import()来装载Components。但目前你正使用的这个版本,应该已经缺省包含了。在任
何情况下,你可以自行发布一个Qomo的集成(build)版本。这需要你用Qomo包中的:
Build\TestCase\T_CustomBuilder.html
来产生一个自己需要的Qomo代码包。记得选中“载入扩展界面控件”就好了。
上面这个例子说明,你可以为任意界面上的HTML元素添加一个THtmlController控制。它封
装了界面上的HTML元素的一些细节,如果你需要访问原始的HTML属性,那么使用el.get()
就可以了。
五、让Qomo做一个Html的控件
-----
更进一步的说,你可以将任何界面上的一组Elements封装成为一个Qomo的类。这个类可以认
识界面上的这些组合在一起的东西是一个控件,或者其它。一个较为浅显的例子是:我们可
以将一个div与一个edit放在一起,使它变成一个TLabledEdit。这是个不错的主意:
- <scriptsrc="js/Qomo.js">script>
-
- <body>
- <divid="edLabled"><span>hello,TLabledEdit.span><br>
- <inputname="edit"value="...">
- div>
- body>
-
- <script>
- //后续将说明的代码
- //……
- script>
那么我们到底如何将它实现为一个Html控件呢?首先,我们要在准确地找到所有要控制的
元素。下面是这样的一个基本框架:
- functionLabledEdit(){
- Attribute(this,'_label',null,'r');
- Attribute(this,'_edit',null,'r');
-
- this.get_label=function(){
- returnthis.assignedElement.children(0);
- }
- this.get_edit=function(){
- returnthis.assignedElement.children('edit');
- }
-
- //..其它的实现代码
- }
接下来,我们可以尝试为这个控件添加几个特性,以直接控制界面上的东西:
- functionLabledEdit(){
- //(略,同上...)
-
- this.getLableText=function(){
- returnthis.get('_label').innerText;
- }
- this.setLableText=function(v){
- this.get('_label').innerText=v;
- }
-
- this.getvalue=
- this.getValue=function(){
- returnthis.get('_edit').value;
- }
-
- this.setvalue=
- this.setValue=function(v){
- this.get('_edit').value=v;
- }
- }
然后注册它:
- TLabledEdit=Class(THtmlController,'LabledEdit');
- vared=TLabledEdit.Create('edLabled');
- alert(ed.get('LableText'));
- ed.set('LableText','mylable:');
- ed.set('Value','hello,world.');
六、如此麻烦地做一个组件有什么价值?
-----
有什么价值呢?如果我们的确需要控制这么一个“看起来象组件的HTML代码块”,那么
我们直接用几行脚本就可以办到。例如:
- document.getElementById('edLabled').children(2).value='hello,world.';
- //...
然而,组件系统的真正价值在于复用,类继承的价值亦复如此。如果偏离了复用来讨论
上述的一切,那无异于隔靴搔痒。我们来想象一下,如果我们需要一个使用FieldSet来
做标签的edit,那么又该如何做呢?更多的Editor?
好,我们在Qomo中基于上面的TLabledEdit代码来做一个。
-
"edLabled2"> -
"edit"value="..."> -
- functionFieldSetEdit(){
- }
- TFieldSetEdit=Class(TLabledEdit,'FieldSetEdit');
-
- //示例
- vared=TFieldSetEdit.Create('edLabled2');
- ed.set('Value','hello,world.');
是的。尽管两个组件的表达形式完全不一样,但是由于我们分离了逻辑实现与界面表
面,所以我们只需要调整少数(甚至于象这样无需修改)就可以适应变化了。
Oh。有高手看出来了,我实际上偷了个懒:这里的edLabled2的“HTML结构”与前一
种没有本质的不同。是的,好吧,为了让你相信Qomo具有“节省代码”的能力,那么
我们就弄复杂一点。
七、将一个控制层的组件,复用在其它框架库中
-----
我们找一个相对复杂的Edit,例如我们拿一个YahooUI中的、能自动完成的Edit。大概,
我们要装入一个YahooUI,然后初始化它。最后,再装入我们的代码。OK,就象这样:
-
"stylesheet"type="text/css"href="yui/build/fonts/fonts-min.css"/> -
"stylesheet"type="text/css"href="yui/build/autocomplete/assets/skins/sam/autocomplete.css"/> -
"text/javascript"src="yui/build/yahoo-dom-event/yahoo-dom-event.js"> -
"text/javascript"src="yui/build/animation/animation-min.js"> -
"text/javascript"src="yui/build/datasource/datasource-min.js"> -
"text/javascript"src="yui/build/autocomplete/autocomplete-min.js"> -
- class="yui-skin-sam">
Enterastate:
-
"myAutoComplete"> -
"myInput"type="text"> -
"myContainer">