Creating Controls
enyo.Control
enyo.Control是控制DOM节点的组件。control通常都是可见的,用户经常与他们直接交互。诸如按钮和输入框显然是control,但是在enyo中control可能变得像整个应用程序一样复杂。
The Basics
在下面的例子中,我们定义了一个名为Circle的control,稍后它会用在一个名为TrafficLight的control内部:
1 enyo.kind({ 2 name: "Circle", 3 kind: "Control", 4 published: { 5 color: "magenta", 6 bgColor: "black" 7 }, 8 handlers: { 9 ondown: "downHandler", 10 onup: "upHandler" 11 }, 12 content: "Hi", 13 style: "padding: 2px 6px; border: 3px solid; border-radius: 20px; cursor: pointer;", 14 create: function() { 15 this.inherited(arguments); 16 this.colorChanged(); 17 }, 18 colorChanged: function() { 19 this.applyStyle("border-color", this.color); 20 }, 21 bgColorChanged: function() { 22 this.applyStyle("background-color", this.bgColor); 23 }, 24 downHandler: function(inSender, inEvent) { 25 this.applyStyle("background-color", "white"); 26 }, 27 upHandler: function(inSender, inEvent) { 28 this.applyStyle("background-color", "black"); 29 } 30 });
这个Circle的kind值为“Control”并且继承扩展了enyo.Control的行为。由于control是一个组件(enyo.Control继承自enyo.Component,enyo.Component继承自enyo.Object),它可以像这里这样公布属性。
Manipulating a Control's DOM Node
一个control暴露控制自身DOM节点的方法。注意在圆中使用的内容和样式。Content属性设置了control要渲染的html内容。由于control对象公开了content属性,你可以调用setContent和getContent方法访问content属性。指定的css样式用来装饰节点。你可以指定样式、属性甚至标签类型。例如:
{tag: "input", classes: "rounded", attributes: {value: "foo"}}
这些属性既可以设置在control的参数中也可以定义在kind中。
还有几种方法来修改这些属性,例如applyStyle设置指定的样式属性。其他类似方法有addStyles,addClass,setAttribute,show,hide和render。更多的详细信息请参照API文档。
Controls in Controls: It's Those Turtles Again
我们前面所述的TrafficLight control:
1 enyo.kind({ 2 name: "TrafficLight", 3 kind: "Control", 4 style: "position: absolute; padding: 4px; border: 1px solid black; background-color: silver;", 5 components: [ 6 {kind: "Circle", color: "red", ontap: "circleTap"}, 7 {kind: "Circle", color: "yellow", ontap: "circleTap"}, 8 {kind: "Circle", color: "green", ontap: "circleTap"} 9 ], 10 circleTap: function(inSender, inEvent) { 11 var lights = {red: "tomato", yellow: "#FFFF80", green: "lightgreen"}; 12 if (this.lastCircle) { 13 this.lastCircle.setBgColor("black"); 14 } 15 this.lastCircle = inSender; 16 this.lastCircle.setBgColor(lights[inSender.color]); 17 } 18 });
因为他们都是组件,control可以包含其他的control。一个control会渲染自身包含的所有control。这样,TrafficLight会渲染自身内部的三个Circle实例,如果我们的样式正确它看起来会像真正的交通红绿灯。
注意如果control包含其他有content值的control,它会渲染子control并忽略content的值。
Controls and Events
Enyo control能够处理一般的DOM事件。在component的参数设置里,指定处理DOM事件的处理函数和其他enyo事件一样使用委托名称。TrafficLight kind通过设置 ontap:"circleTap"来指定circle control的处理函数。因为TrafficLight有自己的circle,它会处理它们的事件。这样,circleTap应该作为TrafficLight内部处理方法的名称。
现在,ontap事件不是DOM本身的事件。它实际上是一套跨平台事件,看起来就像DOM事件。 Enyo将不同平台的事件进行规范,这样用户就可以为应用编写一套能够同时运行在移动和桌面平台上的事件处理函数。
注意Circle kind处理一些自身的事件。当用户按下和释放时它会有相应的反应。Kind要处理的DOM事件(包括类DOM事件)在handler语句块中指定。Circle kind指定了down和up事件的处理函数。这些handler的名字和Circle kind中处理事件方法的名字一样。严格来说,down和up事件并不是DOM事件,而是类DOM事件。
和所有的事件一样,第一个参数是inSender对象。DOM和类DOM事件通过第二个参数传递事件对象。
因为DOM和类DOM事件通过DOM冒泡传递,它们可能被控制层的任一control处理。例如,一个TrafficLight的用户可以实现一个ontap的事件处理程序并接收来自trafficLight内部的tap事件。