发布和响应事件
iWidget 的一个强大的能力是可以发布和响应事件。通过事件机制,多个 iWidget 可以协同工作,以完成复杂的业务场景。每个 iWidget 可以声明其发布出来的事件,以及它可以响应的事件。在运行时刻,每个事件都可以附带一定类型的数据(payload)。
iEventDescription 和 iEvent
对于 iWidget 的每个事件,iWidget 规范中定义了 iEventDescription 来描述它。iEventDescription 中提供的属性和方法见 表 5。
表 5. iEventDescription 的属性和方法
| 名称 | 说明 |
|---|
| name | 该属性表示事件的名称。 | | type | 该属性表示事件附带的 payload 的类型。 | | getDescription() | 该方法用来获取事件的描述。事件的描述是与当前用户的区域设置(locale)相关的。该方法有一个参数用来指明区域设置,默认值是“ en ”。 | | handlingFn | 当声明一个 iWidget 可以响应的事件时,该属性用来表示响应该事件的方法名称。 |
当一个事件在运行时刻被发布的时候,iEvent 用来描述该事件的运行时信息。iEvent 中的属性见 表 6。
表 6. iEvent 的属性
| 名称 | 说明 |
|---|
| name | 该属性表示事件的名称。 | | type | 该属性表示事件附带的 payload 的类型。 | | payload | 该属性表示事件的 payload 。一般是 JavaScript 中的简单数据类型、JSON 对象或是 JavaScript 对象。 | | source | 该属性表示事件的发布者。 |
响应事件
在 HelloWorld iWidget 中,目前生成的问候语的对象总是“ World ”。下面将通过事件机制来允许其它 iWidget 将要问候的对象名称传递给 HelloWorld,这样就可以生成“你好 Alex ”这样的问候语。
要为 HelloWorld iWidget 添加响应事件,需要修改其定义文件,以增加对事件的声明。清单 9 中给出了事件的声明。
清单 9. HelloWorld 中声明响应事件
<iw:event id="greetingSubject" handled="true" eventDescName="desc_greetingSubjectChanged"
onEvent="onChangeGreetingSubject" />
<iw:eventDescription id="desc_greetingSubjectChanged"
payloadType="text" description="Subject of the greeting" lang="en">
<iw:alt description=" 问候对象 " lang="zh" />
</iw:eventDescription> |
清单 9 中使用了 event 和 eventDescription 两个元素用来声明事件。其中 event 的 id 属性表示的是事件的名称,对应于 表 5 中 name;handled 属性的值为 true 表示这是一个由 iWidget 响应的事件;eventDescName 属性表示与该事件对应的事件描述的名称;onEvent 属性表示该事件的响应方法名称。eventDescription 的 id 表示该事件描述的名称;payloadType 属性表示事件的 payload 的类型,此处是纯文本(text);description 表示该事件描述的说明;lang 表示说明所使用的语言;alt 元素用来提供其它语言的说明。
在 HelloWorld iWidget 对应的 JavaScript 对象中需要添加前面提到的事件 greetingSubject 的响应方法,即 onChangeGreetingSubject 方法,见 清单 10。
清单 10. HelloWorld 中事件的响应方法
onChangeGreetingSubject : function(iEvent) {
var subject = iEvent.payload || "";
var messageDom = this.byId("message");
var settingsObj = this.loadSettings();
messageDom.innerHTML = this.HELLOS[settingsObj["language"] || "en"] + " " + subject;
} |
事件的响应方法的第一个参数是 iEvent 的实例,其属性如 表 6 中所示。清单 10 中的响应方法根据事件的 payload 内容和从配置中读取的语言来构建问候语。
下面通过一个 IBM Mashup Center 中实际的页面来展示 HelloWorld iWidget 的事件响应。该页面使用“用户输入” iWidget 和 HelloWorld iWidget 。“用户输入” iWidget 可以接受用户的输入并作为事件发布出来,发布出来的事件由 HelloWorld iWidget 来响应。页面上展示的效果是当用户输入不同的文本时,HelloWorld iWidget 给出的问候语也会发生变化,如 图 5 所示。
图 5. HelloWorld iWidget 的事件响应效果图
发布事件
上一节中介绍了如何让 iWidget 响应其它 iWidget 发布的事件,本节介绍如何发布事件给其它 iWidget 。通过为 HelloWorld iWidget 增加一个发布的事件,可以将其生成的问候语发布给其它 iWidget 。清单 11 中给出了发布的事件的声明。
清单 11. HelloWorld 中声明发布事件
<iw:event id="greeting" published="true" eventDescName="desc_greeting" />
<iw:eventDescription id="desc_greeting"
payloadType="text" description="Greeting" lang="en">
<iw:alt description=" 问候语 " lang="zh" />
</iw:eventDescription> |
清单 11 与 清单 10 一样,同样是使用 event 和 eventDescription 两个元素来声明事件。不同的是 event 的 published 属性为 true,表示这是一个发布的事件。
在声明了发布的事件之后,需要在适当的时机把该事件发布出来。由于问候语由问候的对象和所用的语言来确定,因此当两者中的任何一个发生变化时,都需要发布事件。清单 12 中给出了相关的实现。
清单 12. HelloWorld 中发布事件
publishGreeting : function() {
var messageDom = this.byId("message");
var greeting = messageDom.innerHTML;
this.iContext.iEvents.fireEvent("greeting", null, greeting);
} |
清单 12 中的 publishGreeting 方法用来发布事件。它使用了 iContext.iEvents.fireEvent 这个方法来完成事件的发布。iContext.iEvents.fireEvent 方法的三个参数分别表示事件的名称、payload 的类型和 payload 本身,其中后两个参数是可选的。 payload 的类型如果是 null 则表示类型信息是不可见的。
下面对上节中提到的页面进行修改来展示 HelloWorld iWidget 的事件发布。在该页面中增加一个“事件资源管理器” iWidget 用来查看 HelloWorld iWidget 发布的事件,如 图 6 所示。
图 6. HelloWorld iWidget 的事件发布效果图
在 IBM Mashup Center 中可以通过“查看连线图”来查看当前 iWidget 与页面上其它 iWidget 之间的事件关联。图 7 给出了 HelloWorld iWidget 的事件关联。
图 7. HelloWorld iWidget 的事件关联
预定义 payload 数据类型
前面提过在 iEventDescription 中可以使用 type 来声明事件发布时所附带的 payload 的数据类型,在之前的 HelloWorld 的例子中,使用的是预定义的简单数据类型 text。实际上,除了 text 之外,运行环境还提供了许多预定义的 payload 类型。使用这些预定义的类型可以减少歧义,使得你的 iWidget 发布的数据能更加容易的被其它 iWidget 所理解。表 7 中列出了常用的预定义 payload 数据类型。
表 7. payload 的通用数据类型
| 名称 | 说明 |
|---|
| 简单类型 | 简单类型有 text、url、number、boolean、date、time、timestamp、email 和 currency 等,分别表示文本、URL、数字、布尔型、日期、时间、时间戳、电子邮件地址和货币等。 | | table | 表示表格型数据的复杂类型。 | | atom | 表示 ATOM 订阅源的复杂类型。 | | xml | 表示一般格式的 XML 文档的复杂类型。 | | json | 表示 JSON 对象的复杂类型。 |
小结
本章中介绍了如何在 iWidget 中发布和响应事件,并对事件 payload 的数据类型做了说明。下一章将讨论 iWidget 开发中的几个高级话题。
|