内容


XPages 揭秘

Comments

编者注:对此话题十分了解?要分享您的专业经验?现在立即参与 IBM Lotus software wiki 计划。

简介

XPages 开发通常依赖于两个传统设计元素:用于定义数据的表单和用于报告数据的视图。但是,它们不是绝对需求。您可以使用 JavaScript 在控件和 Lotus Domino 数据存储之间移动数据。JavaScript 并不难。

出于以下原因,您可能不想采用 JavaScript 方法:

  • 表单和视图允许您可视地定义复杂的结构。
  • 将必要的表单和视图放到一起后,开发进展地非常顺利。例如,将表单中的字段绑定到 XPage 中的控件只需将字段拖放到控件上即可。
  • 如果将 XPages 放到现有 IBM Lotus Domino Designer 应用程序中,您可能希望利用现有表单和视图。

但是如果对 Lotus Domino Designer 不熟悉,表单和视图设计将需要一定时间的学习。即使了解 Lotus Domino Designer,表单和视图也要求您跳出 XML 模式。您会发现自己就是在处理 @函数和 LotusScript®。

本文介绍如何使用 JavaScript 在 IBM Lotus Domino 应用程序中创建、查看、编辑和删除文档。它展示了如何将数据从这些文档绑定到 XPage 的控件上。

本文还简要介绍了 XPages 中的 JavaScript。XPages 中的 JavaScript 最强大的地方就是能够访问大量的库,从而方便地操纵用户环境和后端数据存储。如果熟悉 LotusScript,您会了解 NotesSession、NotesDatabase、NotesDocument 以及很多其他 Domino 对象。JavaScript 中也有同样的对象,只是它们在源代码中的部署更为简单。

最后,本文展示了在哪里以及如何在 XPages 用户界面(UI)中添加 JavaScript。您可以使用 JavaScript 返回值,例如,计算后的字段返回值。您可以将 JavaScript 添加到事件,例如,按钮的 onclick 事件。您还可以使用 JavaScript 定义属性,例如,控件的 Visual 属性是 true 还是 false。

世界你好

启动 Lotus Domino Designer 并创建一个应用程序。在左侧(导航器)的应用程序名称下面,右键单击 XPages 并选择 New XPage。为 XPage main 命名并单击 OK。此操作会在页面中间显示一个编辑器并在右侧显示一组控件。如果没有控件或出于某种原因您关闭了该选项卡,可以通过选择 Window - Show Eclipse Views - Controls 重新显示这些控件。

对于此新页面中的第一个设计操作,可以从 Controls 中将 Computed Field(可能需要向下滚动)拖动到中央调板。此外,可以双击 Computed Field,它会显示在编辑器中。焦点停留在计算字段和选择的 Properties 选项卡上,您的视图应该如图 1 所示。

图 1. 带有 Computed Field 控件的 XPage
带有 Computed Field 控件的 XPage
带有 Computed Field 控件的 XPage

现在我们为此计算字段设置一个值。选择 Value(在 Properties 下面)并选择 JavaScript。可以直接向显示的窗口中键入脚本,但是这里我们单击窗口右侧的 Open Script Dialog 按钮,如图 2 所示。

图 2. 选择 JavaScript 设置值
选择 JavaScript 设置值
选择 JavaScript 设置值

注意脚本编辑器左侧的全局对象,如图 3 所示。(如果没有选择 Reference,则选择该选项卡。如果没有选择 Global Objects,则从 Libraries 下面的下拉菜单中选择它)。向下滚动列表并双击会话。它会显示在编辑器中。键入句点并稍等片刻后,会显示方法列表。向下滚动并双击 getCommonUserName(): 字符串。

图 3. session 全局对象的内容助手
session 全局对象的内容助手
session 全局对象的内容助手

全局对象是 Lotus Domino 服务器上 XPages JavaScript 可用的对象层次结构的入口点。session 对象允许您访问 Lotus Domino 会话及其底层对象。如图 4 所示,打开左侧 Reference 下面的 session。您会看到与您在会话后键入句点时出现在编辑器中的方法同样的方法。

图 4. 在 Reference 窗格中展开 session 对象
在 Reference 窗格中展开 session 对象
在 Reference 窗格中展开 session 对象

现在从 Libraries 下面的下拉列表中选择 Domino。向下滚动并打开 NotesSession。如图 5 所示,您会再一次看到同样的列表。session 全局对象实际上是当前用户的 Lotus Domino NotesSession 对象。

图 5. 在 Reference 窗格中展开 Domino NotesSession 对象
在 Reference 窗格中展开 Domino NotesSession 对象
在 Reference 窗格中展开 Domino NotesSession 对象

调整代码使其看起来像这样:

return "Hello " + session.getCommonUserName()

return 关键字是隐式的,因此代码还可以写为:

"Hello " + session.getCommonUserName()

关闭脚本编辑器,单击 OK 保存编辑。

通过选择 Design - Preview in Web Browser(或 Preview in Web Browser 快捷方式)并选择浏览器您可以预览您的作品。(至少需要通过作者权限才能先将 Anonymous 添加到应用程序的 ACL)。预览时,Lotus Domino 会在计算机上启动一个 miniserver。

预览页面的 URL 采用 http://localhost/foo.nsf/main.xsp 的形式。如果之前预览过并且如果 Lotus Domino Designer 仍在运行(因为 miniserver 必须运行),则可以直接向浏览器键入此 URL。如果应用程序在 Lotus Domino 服务器上,请使用服务器名,不要使用 localhost。

从 Lotus Domino Designer 8.5.1 开始,您还可以选择 Design - Preview in Notes( Preview in Notes 快捷方式)。

要设置应用程序,使其通过 XPage 在 Lotus Notes® 中启动,在导航器底部选择 Application Properties。显示应用程序属性时,选择 Launch 选项卡。将 Launch 选项设置为 Open designated XPage (Standard client) 并指定 XPage。

稍后您将看到,应用程序启动后如何从一个 XPage 转到另一个。如果处于非 XPage 设计元素中,您可以按以下公式中显示的形式应用 Lotus Notes URL(此示例是视图中的一个操作)。

@URLOpen("notes:///foo.nsf/main.xsp?OpenXPage")

在服务器上,像这样插入服务器名称:

@URLOpen("notes://myserver/foo.nsf/main.xsp?OpenXPage")

在深入研究数据之前,还有一个项目值得注意。在编辑器底部,如图 6 所示选择 Source。定义您 XPage### 的 XML 将会显示。您可以直接编辑 XML,无需在可视化编辑器中编辑。选择 Design 回到可视化编辑器。

图 6. XPage 的源 XML
XPage 的源 XML
XPage 的源 XML

数据你好

我们将 XPage 上的另一个计算字段放在第一个的下面。按回车键,然后双击并拖动另一个 Computed Field 控件。单击 Properties 下面的 Value,单击 JavaScript 并单击 Open Script Dialog 按钮。

您再次位于脚本编辑器中。无需打开脚本编辑器。如前所述,可以在 JavaScript 按钮下面的窗口中编辑脚本,如图 2 所示。还可以通过使用 Source 选项卡在 XML 中编辑脚本。但是脚本编辑器提供了更大的空间并且左侧有 Reference 和 Outline 选项卡。

在 Reference 选项卡中,在 Global Objects 下向下滚动,双击数据库,如图 7 所示。当它显示在编辑器中时,在其后键入句点并等待方法列表显示。这是另一个非常有用的全局变量。它会为当前数据库创建 NotesDatabase 对象,也就是包含此 XPage 的应用程序。

图 7. 数据库全局对象内容助手
数据库全局对象内容助手
数据库全局对象内容助手

双击 getAllDocuments(): NotesDocumentCollection。键入另一个句点显示属于 NotesDocumentCollection 对象的方法列表,其中之一是 getCount(): int。双击该方法并键入另一个句点。此时,方法列表是针对 String 类的,它在 Standard 库中。双击 toFixed(): string。此时,您的脚本内容是:

database.getAllDocuments().getCount().toFixed()

此脚本统计当前数据库中所有文档的数量,值为字符串。修改此脚本,使其如下所示:

return "Number of documents in database: " + database.getAllDocuments().getCount().toFixed()

单击 OK,保存并预览。对于新应用程序,预览显示数据库中有零个文档。

仅出于提供信息的目的(不是样例应用程序的一部分),以下是获取指定数据中文档数量的代码。session.getDatabase 的第一个参数是服务器名称,其中 null 意味着是本地系统。第二个参数是应用程序相对于 Lotus Notes 数据目录的名称。

return session.getDatabase(null, "fooA.nsf").getAllDocuments().getCount().toFixed()

清单 1 显示了代码,该代码获取本地 Lotus Notes 目录中所有 NSF 应用程序的名称。session.getDbDirectory 返回的对象是 NotesDbDirectory 类型。其 getFirstDatabase 和 getNextDatabase 方法返回 NotesDatabase 类型的对象。

清单 1. 获取所有 NSF 应用程序名称的代码
	var list = "";
	var dir = session.getDbDirectory(null);
	var db = dir.getFirstDatabase(1247); // 1247 = type DATABASE
	while (db != null) {
		if (!list.isEmpty()) list = list + ", ";
		list = list + db.getFileName();
		db = dir.getNextDatabase();
	}
	return list

创建文档

创建文档的第一个任务是从 XPage 获取用户数据。为此,我们创建两个字段,一个字符串和一个数字。

  1. 创建一个 2 乘 2 表格。在 Container Controls 下面查找 Table 控件。
  2. 在第一列中,放置 Label 控件,其标签显示主题和数量。
  3. 在第二列中放置 Edit Boedit。

可视化编辑器的内容应该如图 8 所示。

图 8. 主题和数量编辑框
主题和数量编辑框

编辑框旨在允许用户键入某些内容。但是如何访问这些内容?如果正使用 Lotus Domino 表单备份 XPage,您要将每个编辑框绑定到表单的字段上。此方法会在本文最后略加介绍。出于编程目的,您要将每个字段绑定到全局变量。

将焦点放在第一个编辑框上,然后在 Properties 下面选择 Data。选择 Advanced。从下拉列表中,选择 Scoped Variable。在 Parameter 字段中,从列表中选择 Request Scope。最后,为变量起个名字。我们将这个变量叫做 subject。请参见图 9。

图 9. 将字段绑定到范围变量
将字段绑定到范围变量
将字段绑定到范围变量

当服务器根据 URL 请求处理页面时,此变量可供页面使用。服务器处理完 URL 请求时它丢弃范围并释放内存。从下拉列表中您能看到有四种范围变量。按降序排列,它们是 Application Scope、Session Scope、View Scope 和 Request Scope。

以同样的方式,将第二个编辑框绑定到名为 number 的 Request Scope 变量。这里,您必须制定一个额外的规则。将显示类型改为 Number 至关重要,因为您希望将此输入视为数值数据。请参见图 10。

图 10. 将字段绑定到类型为 Number 的范围变量
将字段绑定到类型为 Number 的范围变量
将字段绑定到类型为 Number 的范围变量

现在,我们来看一下如何创建文档。这并不难!

在编辑框下面放置一个 Button 控件。将标签改为 Create document。

选择 Events 选项卡。左侧是此控件可以使用的事件。您需要 onclick,它已经被默认高亮显示。然后选择 Script Editor 并确保选中了 Server 选项卡(默认情况下,它是选中的)。请参见图 11。

图 11. 为按钮指定事件
为按钮指定事件
为按钮指定事件

可以直接在窗口中输入脚本或者单击右侧的 Open Script Dialog 按钮。该操作将显示模式脚本编辑器,其左侧带有 reference 选项卡。

清单 2 显示了脚本。

清单 2. 用于创建文档的 JavaScript
	var doc = database.createDocument();
	doc.replaceItemValue("subject", requestScope.subject);
	doc.replaceItemValue("number", requestScope.number)
	doc.save();
	requestScope.subject = null;
	requestScope.number = null

第一行创建一个 NotesDocument 对象。下两行用项目值填充该对象,项目值是基于绑定到编辑框控件的全局变量的。注意,正确的规范是范围后面跟有句点,句点后面跟有变量名。预期的情况是用户已经在这些框中输入了值。另请注意 subject 和 number 都在引号中。这些需要您进行创建并提供文档中项目的名称。在执行 save 方法之前,数据存储中不会发生任何操作。最后,清除范围变量,这样旧值不会出现在 UI 中并且不会影响未来的事件。

保存并预览页面。输入 subject 和 number,然后单击 Create document。单击按钮使带有页面信息的 URL 发送到 Lotus Domino 服务器(在预览情况下发送到 miniserver)。服务器处理事件代码并将修订的页面发送回浏览器(或 Lotus Notes 客户端)。试几次后,您会看到文档计数在增加。

查看文档

看到文档计数在增加,就知道有事件发生。了解一些细节会很有帮助。查看遗留 Lotus Domino 中数据的常用方法是使用 View 设计元素。XPages 拥有一个视图控件,该控件含有视图设计元素。但是您要使用数据表控件和一些 JavaScript。

将焦点放到按钮下面。从 Container Controls 中双击或拖动 Data Table 控件。在 Properties 下面选择 JavaScript 并输入返回文档集合的脚本。本示例中第二个重要的规范是您提供的集合名 rowdoc。请参见图 12。

图 12. 指定 Data Table 控件
指定 Data Table 控件
指定 Data Table 控件

数据表作用于指定的集合。本例返回数据库中所有文档的集合。在程序中有很多方式可以修改集合来返回文档的子集,包括全文搜索。

在数据表内右键单击,然后选择 Insert Column 或 Append Column。注意,显示的列有三行。顶行和底行本质上是静态的并包含您输入内容的一个副本。使用顶行作为标头;插入 Label 控件,该控件的标签是 subject。

中间一行本质上是一个 Repeat 控件。Repeat 控件是有值的。就数据表而言,Repeat 控件根据基本集合中对象的数量提供一个变化的行数。每行用于集合的一个成员。本例使用当前数据库中所有文档的 NotesDocumentCollection。集合的每个成员都是 NotesDocument 类型的对象。还记得集合名是 rowdoc?该名称指向与当前行相关的 NotesDocument 对象,也就是用户所在行。

将焦点放到中间行。从 Core Controls 中,双击或拖动 Computed Field 控件。在 Properties 下选择 Value。对于该值,选择 JavaScript 并输入脚本。该脚本使用 rowdoc(前面提到的 NotesDocument 对象)的 getItemValueString 方法获取 subject 项的值。请参见图 13。

图 13. 为重复行指定值
为重复行指定值
为重复行指定值

内容助手这时会在旁边提示:不幸的是,在 rowdoc 后键入句点并没有出现方法列表,因为编辑器不知道 rowdoc 的类型。您必须使用 reference 窗格或文档准确地输入方法名。在 reference 窗格中,可以双击使方法显示在编辑器中。另外,可以应用一个 hack 迫使内容助手先输入一行良性代码确定类型再开始工作。在下面的代码中,内容助手知道 rowdoc 是 NotesDocument 类型并显示了其方法。

rowdoc:NotesDocument == null;
return rowdoc.

预览显示带有一个列的表格,subject 是列的标头,行包含当前数据库中每个文档的 subject 值。

将焦点放到数据表(而不是列)上,右键单击并选择 Append Column。通过与前面一样的过程,为 number 项创建一个列。这次,计算字段的脚本如下所示:

return rowdoc.getItemValueDouble("number")

最后,再添加一列显示修改日期。脚本如下所示:

return rowdoc.getLastModified()

预览现在显示三列,它们是主题、数量和最后一次修改日期。

编辑和删除

我们提供一种方式来编辑现有文档。

将另一列追加到数据表。双击或拖动 Button 控件到中间行,编辑其标签。选择 Events 选项卡,确保选中了 onclick 和 Server 选项卡并选择 Script Editor。输入以下脚本:

sessionScope.docUnid = rowdoc.getUniversalID();
requestScope.subject = rowdoc.getItemValueString("subject");
requestScope.number = rowdoc.getItemValueDouble("number")

此代码将全局变量设置为文档通用 ID 的值加上两项的值。通用 ID 需要 sessionScope 变量,因为它的使用跨越两个请求。

最后两个变量绑定到编辑框。用户单击编辑按钮时,URL 指向 Lotus Domino 服务器。该服务器发送回带有两个编辑框的页面,编辑框用来自数据表的该行的值填充。用户可以编辑数据。在图 14 中,用户单击了第二行的编辑按钮。

图 14. 获取一行数据进行编辑
获取一行数据进行编辑
获取一行数据进行编辑

现在需要一个按钮做替换工作。将该按钮放到 Create document 按钮旁边,其标签为 Replace document。先以复制和粘贴 Create document 按钮作为开端。对于其 onclick 事件,使用清单 3 中的 JavaScript 代码。该代码与 Create document 按钮的代码一样,只是第一行有所不同,第一行使用其通用 ID 获取现有文档而不是创建文档。

清单 3. 替换文档中值的 JavaScript
	var doc = database.getDocumentByUNID(sessionScope.docUnid);
	doc.replaceItemValue("subject", requestScope.subject);
	doc.replaceItemValue("number", requestScope.number)
	doc.save();
	requestScope.subject = null;
	requestScope.number = null

您还要提供一个 Cancel 按钮,其代码如下。它无需在数据库中进行任何更改便可清空编辑框。

requestScope.subject = null;
requestScope.number = null

为了获得更好的可用性,可以选择将以下代码行添加到编辑按钮的 onclick 事件。

sessionScope.editMode = true

将以下代码行添加到 Replace document 和 Cancel 按钮的 onclick 事件。

sessionScope.editMode = false

此添加的代码行使 editMode 全局变量仅在用户编辑时为 true。其他情况下,它是未初始化或 false 的。现在,转到表上面三个按钮的属性。向下找到 Visible 属性。单击菱形,选择 Compute value。对于 Create document 按钮,使用以下脚本:

sessionScope.editMode != true

对于 Replace document 和 Cancel 按钮,使用此脚本:

sessionScope.editMode == true

现在用户进入文档,只有 Create document 按钮可见。用户单击编辑按钮时,Create document 按钮消失,显示其他两个按钮。

删除文档很简单。另外附加一列,并将按钮放到中间行。将按钮标为 remove。对于 onclick 事件,使用以下代码:

rowdoc.remove(true)

目前您看到的代码都是服务器端的。代码在浏览器或 Lotus Notes 客户机将页面传递到服务器后执行。JavaScript 是标准的,没有什么例外,但是它需要访问其他库,特别是,Domino 对象的库。

您还可以提供客户机端 JavaScript。此代码在页面进入服务器之前,在浏览器或 Lotus Notes 客户机上执行。针对您正在使用的客户机的 JavaScript 是标准的并且能够访问标准的 Web DOM。

您可以为同样的事件既提供服务器端脚本又提供客户机端脚本。客户机端脚本通过返回 false 防止服务器端操作的执行。

在此样例应用程序中,您可以使用客户机端脚本确认文档的删除。再次,转向 remove 按钮的 onclick 事件。在此已经有了服务器代码。如图 15 所示,选择 Client 选项卡,选择 Script Editor 并输入以下代码:

return window.confirm(“Do you really want to delete this document?”)

图 15. 事件的客户机端代码
事件的客户机端代码
事件的客户机端代码

用户单击按钮时,客户机端脚本显示一个确认窗口。单击确定返回 true,执行服务器端脚本。单击 Cancel 返回 false,服务器端代码不执行。

使用多个页面

下面我们处理一下更为典型的场景,用户从不同的页面提交数据。开始之前,最好对主 XPage 进行备份。

创建一个名为 create 的 XPage。用来自主 XPage 的编辑框剪切 4 乘 4 表并将其粘贴到 create XPage。从主页面复制(不要剪切)Create document 和 Cancel 按钮并将其粘贴到 create XPage。在 create XPage 中,将焦点放到 Create document 按钮上并将其标签改为 Submit。为两个按钮改变 Visible 属性,使其总是可见。请参见图 16。

图 16. 用于创建文档的 XPage
用于创建文档的 XPage

编辑框不用修改,但是按钮代码必须调整。打开 Submit 按钮 onclick 事件的脚本编辑器。前四行用于创建文档,其工作方式一样。清空编辑框的后两行则不需要用到,因为您要离开这个页面。最后,必须添加一行将用户带回主页面。代码如清单 4 所示。

清单 4. 创建文档并打开另一个页面的 JavaScript
	var doc = database.createDocument();
	doc.replaceItemValue("subject", requestScope.subject);
	doc.replaceItemValue("number", requestScope.number)
	doc.save();
	context.redirectToPage("main")

上下文全局对象属于 XSP 库中的 XSPContext 类型。

对于 Cancel 按钮,要删除现有代码并用 Submit 脚本中的最后一行代码替换它。也就是将用户带到主页面。另一种完成此任务的方式是通过简单的操作。转到按钮的 onclick 事件。选择 Simple Actions(如果得到警告,单击 OK),然后选择 Add Action。在显示出的窗口中,确保该 Action 是 Open Page;如果需要可以从下拉菜单中选择它。对于要打开的页面的名称,在下拉菜单中选择 main。然后单击 OK。请参见图 17。

图 17. 打开另一个页面的简单操作
打开另一个页面的简单操作
打开另一个页面的简单操作

还有一种方式返回主页面。将按钮设置为 Cancel 类型并删除所有事件代码。为该页面选择 Properties 选项卡并将 Next 页面(如果更新失败)设置为 main。

现在回到 main XPage 并将焦点放到 Create document 按钮上。删除 onclick 事件的代码(确保在继续前删除代码)。通过这个按钮转到 create XPage。您可以将 JavaScript 与此代码一起使用。

context.redirectToPage("create")

或者可以使用简单的操作。

预览该页面。单击 Create document。键入任意数据。尝试使用 Submit 按钮。然后尝试使用 Cancel 按钮。

接下来,创建名为 replace 的 XPage。从 create XPage 复制所有内容并将其粘贴到 replace。对于此页面,您必须改变编辑框的绑定,将其绑定到 sessionScope 变量,因为数据是跨请求传递的。

对 Submit 按钮需要进行微调。您要使用 main XPage 中设置的通用 ID 获取现有文档,而非创建文档。并且全局变量必须改为 sessionScope。使用 sessionScope 变量后,使其变为 null,如清单 5 所示。

清单 5. 替换文档中的值并打开另一个页面的 JavaScript
	var doc = database.getDocumentByUNID(sessionScope.docUnid);
	doc.replaceItemValue("subject", sessionScope.subject);
	doc.replaceItemValue("number", sessionScope.number);
	doc.save();
	sessionScope.subject = null;
	sessionScope.number = null;
	context.redirectToPage("main")

回到主 XPage,将编辑按钮改为使用 sessionScope 变量,以设置当前项目值和打开 replace XPage,如清单 6 所示。

清单 6. 打开页面以便编辑现有文档的 JavaScript
	sessionScope.docUnid = rowdoc.getUniversalID();
	sessionScope.subject = rowdoc.getItemValueString("subject");
	sessionScope.number = rowdoc.getItemValueDouble("number");
	context.redirectToPage("replace")

现在,您有三个页面:main、create 和 replace。用户在 main 中打开应用程序。单击 Create document 按钮发送它们到带有空白编辑框的 create 页面。submit 或 cancel 操作将它们发送回 main。单击编辑按钮,将它们发送到带有填充的编辑框的 replace 页面。submit 或 cancel 操作再一次将它们发送回 main。

富文本

富文本需要特别注意。您不能简单地设置和获取变量。如果不能立刻理解本部分代码,可以像菜谱一样照搬它。

在 create 表单中,拖动或双击编辑框下面和按钮上面的 Rich Text 控件。按需调整其大小。在属性下面,选择 Data 选项卡,选择 Advanced 并将该控件绑定到名为 body 的 Request Scope 变量。

转到 Submit 按钮的 onclick 事件。将脚本调整到清单 7 所示的样子。新代码在第 4 行以创建 NotesStream 对象开始,在第 8 行以结束该对象结束。绑定到富文本控件的 requestScope.body 全局变量类型为 com.ibm.xsp.http.MimeMultipart。其 getHTML 方法获取作为 XML 的富文本控件的内容。然后,在后端将富文本项创建为 NotesMIMEEntity 对象并使用来自控件的 XML 内容设置其值。其中需要 NotesStream 对象作为中间介质。

清单 7. 创建带有富文本的文档的 JavaScript
	var doc = database.createDocument();
	doc.replaceItemValue("subject", requestScope.subject);
	doc.replaceItemValue("number", requestScope.number)
	var stream = session.createStream();
	stream.writeText(requestScope.body.getHTML());
	var entity = doc.createMIMEEntity("body");
	entity.setContentFromText(stream,"text/html;charset=UTF-8", 1725);
	stream.close()
	doc.save();
	context.redirectToPage("main")

要从后台获取数据到富文本控件,可以使用 NotesMIMEEntity 的 getContentAsText 方法。在 replace 页面上,在编辑框下面添加 Rich Text 控件,就像在 create 页面上的操作一样,只是将其绑定到名为 body 的 sessionScope 变量,而不是 requestScope 变量。在主页面上,转到编辑按钮的 onclick 事件。调整代码使其如清单 8 所示。新代码从第 4 行到第 6 行。从后台获取作为 NotesMIMEEntity 对象的富文本文档,然后使用其 getContentAsText 方法设置富文本控件的值。稍后在 replace 页面上需要第 6 行的副本以进行比较。

清单 8. 打开页面,编辑包含富文本的现有文档的 JavaScript
	sessionScope.docUnid = rowdoc.getUniversalID();
	sessionScope.subject = rowdoc.getItemValueString("subject");
	sessionScope.number = rowdoc.getItemValueDouble("number");
	var entity = rowdoc.getMIMEEntity("body");
	sessionScope.body = entity.getContentAsText();
	sessionScope.bodyCopy = sessionScope.body;
	context.redirectToPage("replace")

在 replace 页面上,必须修改 Submit 按钮,以便在控件值改变时写入富文本控件的值。可以从 create XPage 复制并粘贴代码,但注意要进行必要的修改。请参见清单 9。

清单 9. 替换带有富文本的文档中的值的 JavaScript
	var doc = database.getDocumentByUNID(sessionScope.docUnid);
	doc.replaceItemValue("subject", sessionScope.subject);
	doc.replaceItemValue("number", sessionScope.number)
	if(!sessionScope.body.toString().equals(sessionScope.bodyCopy.toString())) {
		var stream = session.createStream();
		stream.writeText(sessionScope.body.getHTML());
		var entity = doc.getMIMEEntity("body");
		entity.setContentFromText(stream,"text/html;charset=UTF-8", 1725);
		stream.close();
	}
	doc.save();
	sessionScope.subject = null;
	sessionScope.number = null;
	sessionScope.body = null;
	context.redirectToPage("main")

使用表单

出于完整性和对照性,我们重新设计 create 和 replace 页面,将数据绑定到表单并且不使用 JavaScript。如果要保存现有设计,复制 XPages。

在导航器中右键单击 Forms 并选择 New Form。将新表单命名为 main 并单击 OK。使用 Create - Field 创建三个字段:名称为 subject,类型为 Text;名称为 number,类型为 Number;名称为 body,类型为 Rich Text。请参见图 18。

图 18. 带有三个字段的表单
带有三个字段的表单
带有三个字段的表单

您可以将字段放到表单上的任何地方。在本例中,外观并不重要。所以直接保存表单。

打开 create XPage。将焦点停留在 XPage 上,在 Properties 下面选择 XPage 并将 Next 页面(success 或 cancel)指定为 main。此选择意味着在执行 Submit 或 Cancel 按钮(稍后解释)之后,主页面被发送到浏览器(或者 Lotus Notes 客户机)。请参见图 19。

图 19. 指定下一页为打开操作
指定下一页为打开操作
指定下一页为打开操作

选择数据并添加 Lotus Domino Document 数据源。指定当前应用程序、主表单和 Create document 为默认动作。名称 document1 可以保持原样。此方法使表单成为 XPage 数据定义的源。请参见图 20。

图 20. 指定表单为 Xpage 的数据源
指定表单为 Xpage 的数据源
指定表单为 Xpage 的数据源

现在将焦点放到第一个编辑框。选择 Simple 数据绑定。指定数据源为 document1 并将控件绑定到 subject。此引用针对主表单上的 subject 字段。为第二个编辑框进行同样的操作,只是将其绑定到 number。请参见图 21。还可以通过从右侧的数据调板中将字段拖动到控件进行此绑定。

图 21. 将控件绑定到表单中的字段
将控件绑定到表单中的字段
将控件绑定到表单中的字段

将焦点放到富文本控件上。将其绑定到 body。您的 XPage 控件现在绑定到了表单中定义的数据。

将第一个按钮的类型改为 Submit。在 Events 下面,确保删除了所有事件代码。此类按钮不需要代码。请参见图 22。

图 22. 指定按钮类型为 Submit
指定按钮类型为 Submit
指定按钮类型为 Submit

将第二个按钮的类型改为 Cancel。同样,确保删除了所有事件代码或简单操作。

该过程处理 create 页面。它用表单绑定和特殊的按钮类型替换 JavaScript。

以类似的方式重新定义 replace 页面。控件的数据绑定与 create 页面一样。按钮也是一样的。唯一不同的是 XPage 数据的默认操作是 Edit document。

现在转向主页面。删除编辑按钮 onclick 事件的代码并重新指定它为 Open Page 简单操作。您要在 Edit document 模式下打开 replace 页面。 使用 rowdoc 变量(来自数据表)计算要编辑的文档,获取要编辑文档的 UNID(这里,需要使用一些 JavaScript)。请参见图 23。

图 23. 打开页面编辑文档的简单操作
打开页面编辑文档的简单操作
打开页面编辑文档的简单操作

用于打开 create 页面的 Create document 按钮可以保持原样。可以删除 Replace document 和 Cancel 按钮。

现在一切准备就绪。创建和替换文档的 JavaScript 代码被删除。这些功能现在通过设计和绑定数据到表单,使用类型为 Submit 和 Cancel 的按钮并在 submit 或 cancel 操作后设置下一个页面实现。remove 按钮保持原样,因为 JavaScript 解决方案是最为简单的。

您还可以创建 View 设计元素并将其用作 View 控件的基础,替换数据表。edit 和 remove 按钮的功能可以设计到视图中。

结束语

Lotus Domino Designer 使用 Lotus Notes 协议将其后端数据作为 Lotus Domino 应用程序中的 document notes(NSF 文件)进行维护。传统的访问方式是通过名为表单和视图的设计元素,其中表单定义了数据和文档显示的方式,而视图是显示和作用于文档集合的方式。

现在,XPages 设计元素封装了整个用户界面。要定义数据,可以选择将 XPages 控件绑定到表单中的字段。另外,可以通过 JavaScript 和 Domino 对象访问数据。同样,可以使用视图来显示和访问文档集合,当然也可以通过数据表和 JavaScript 进行此设计。


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Lotus
ArticleID=465708
ArticleTitle=XPages 揭秘
publish-date=02012010