Creating Components
enyo.Component对象是组成enyo的基本构件。Components封装了丰富的特性,可以作为modeles组合起来使用,创造复杂的应用。当编写enyo应用时,你通常会创建大量自己的component和control kinds。
The Basics
一个组件是一个Enyo的kind,它可以发布属性、绑定事件、包含其他组件。可以把组件看做是一个包含其他组件、输入(方法和属性的set方法)、输出(事件和属性的get方法)的集合。一个组件控制自己的content并将信息以事件的形式发送给它的父组件或拥有者。下面是一个示例:
enyo.kind({
name: "RandomizedTimer",
kind: enyo.Component,
minInterval: 50,
published: {
baseInterval: 100,
percentTrigger: 50
},
events: {
onTriggered: ""
},
create: function() {
this.inherited(arguments);
this.start();
},
destroy: function() {
this.stopTimer();
this.inherited(arguments);
},
start: function() {
this.job = window.setInterval(enyo.bind(this, "timer"), this.baseInterval);
},
stop: function() {
window.clearInterval(this.job);
},
timer: function() {
if (Math.random() < this.percentTrigger * 0.01) {
this.doTriggered({time: new Date().getTime()});
}
},
baseIntervalChanged: function(inOldValue) {
this.baseInterval = Math.max(this.minInterval, this.baseInterval);
this.stop();
this.start();
}
});
正如名字所示,这是一个简单的随机定时器组件。它是一个enyo.Component kind,所以它继承扩展了enyo.Component对象的行为属性。当计时器触发并暴露一些属性时它生成一个事件来控制触发频率。正如你所见,它直接暴露了属性和事件。
Properties
公开的属性放在一个“published”块中,可以有默认值。为了方便,公共属性都自动添加了set方法、get方法和changed方法(其中get和set方法由enyo.Object类继承而来,调用set方法会进行判断是否调用changed方法,可以查看enyo/source/kernel/Object.js文件,那里定义了enyo.Object类和该类添加getset方法的代码)。例如setBaseInterval 和setPercentTrigger 可以用来改变计时器的频率。
当setBaseInterval被调用时,我们的实现需要我们更新定时器触发代码。这有时被称为属性set方法的一个副作用。它实现了baseIntervalChanged方法,当baseInterval的值发生变化时调用setBaseInterval(要表达的意思应该是当baseInterval的值发生变化时调用setBaseInterval,setBseInterval方法内部会对bseInterval进行判断,如果该属性为空则直接赋值,不为空则调用baseIntervalChanged()方法。这里实在翻译不好,怎么都觉得别扭。)。
注意,通常需要初始化一个属性值。我们通常通过在create方法中调用属性changed方法来初始化。因为需要在不同情况下初始化,我们把它留给component自己判断。
Events
同样,事件被放置在一个“事件”块。触发事件,我们调用相关的“do”方法,enyo提供了另一个便利。例如,为了触发onTriggered事件,我们可以调用doTriggered 方法。 你可以通过“do”的方法来传递一个参数 —— 一个事件对象,该对象将被传递到事件处理程序。在本例中,我们发送当前时间在事件的时间属性。稍后,我们将看到如何处理该事件。
Components in Components: It's Turtles All the Way Down
首先我们创建另一个kind,SimulatedMessage:
enyo.kind({
name: "SimulatedMessage",
kind: enyo.Component,
components: [
{name: "timer", kind: "RandomizedTimer", percentTrigger: 10,
onTriggered: "timerTriggered"}
],
timerTriggered: function(inSender, inEvent) {
this.log("Simulated Service Message Occurred at " + inEvent.time);
}
});
正如您所见,有一个组件和它内部一个配置过的RandomizedTimer。当我们创建一个SimulatedMessage实例,它将创建其中的组件。我们说它拥有这些组件,它负责它们的生命周期。它可以通过使用this.$ hash值来引用这些对象。例如,你可以调用this.$.timer.setPercentTriggered(50)。SimulatedMessage组件的使用者不必关心计时器组件。 它的行为是被封装SimulatedMessage内部的。 所有组件对于他们的拥有者来说都是私有的。
Handling Events
谈到component处理事件这个话题,我们可以把我们的注意力放在onTriggered事件上。注意在配置“timer”对象时我们为onTriggered事件指定的字符串。它就是SimulatedMessage处理onTriggered事件的方法的名称。
事件通过配置名称被委托给组件的拥有者。这是我们免去了add/remove监听机制的痛苦。每一个事件的第一个参数是“inSender”,它是对触发事件的组件的引用。这个方法有利于代码重用,因为同样的方法可以用来处理多个由inSender区分的事件。第二个参数是“inEvent”,是一个传递事件属性信息的对象。
Summary
回顾。components组件以方法、属性和事件的形式封装了行为和接口的基本构件。
下一节
创建Control --
创建Kinds --
英文原文地址: