使用EGL Rich UI访问数据库(5-8课)

第5课 创建服务


本课程将要创建一个访问数据库的EGL专属服务。在本课程中,你将创建一个EGL服务类型,它Handler类似,也一种EGL程序类型,每个EGL程序只能包含一个程序类型,并且类型名称必须与文件名称一致。


5.1 创建一个服务类型

要创建一个服务类型:

  1. 在ProjectExplore窗口中,右击PaymentService,然后点击New> Service

  2. 在NewEGL Service窗口中,输入如下信息:

  1. 在EGLsource file name字段,输入名称SQLService。EGL将自动添加.egl文件扩展。

  2. 在package字段,输入名称services。

  3. 检查Createas web (EGL REST-RPC)没有被选中,然后让Interfacesto implement字段为空。


  1. 点击Finish,EGL将会在编辑器中打开新的服务类型;

  2. 从文件中移除如下代码,只留下如下行,保存文件,暂时不关闭它。

    package services;
    service SQLService
    end

5.2 课程要点

您现在学会了如何创建EGL服务类型。

下节课中,您将添加SQLService函数代码。


第6课 为服务函数添加代码


在EGL中,I/O语句add和get会从不同的数据持久化存储结构中访问数据,如从文件系统、队列、数据库等,它们是相似的。

在本课程中,您将添加关系数据库中访问行记录的函数。请保证函数在SQLService.egl文件中按顺序放置在最后end语句前。


6.1 创建到数据库连接的绑定

在课程3中,您已经定义了一个名为Derby的数据库连接,才用如下步骤来从您的SQL服务中使用Derby连接。

注意:如果您在数据库获取表定义时选择了Savedata source configruation to deploymentdescriptor,SQL绑定则已经包含在了您的部署描述文件(DepoymentDescriptor)中。

PaymentService.egldd则是在定义项目时指定的部署描述文件

点击Ok来关闭窗口。

  1. 在paymentService项目中,右击PaymentService.egldd文件,然后在EGLDeployment Descriptor编辑器中打开。

  1. 选择ResourceBindings标签。

  2. 在SQLDatabase binding中添加一个新的名为Derby的资源绑定类型。

  3. 选中Addthe information from the selected connection below (hard-codedinformation)按钮。注意EDT0.7以前的版本不支持运行时连接。

  4. 选择DerbyConnection细节。

  5. 点击Finish。

  1. 关闭PaymentServices.egldd文件。


6.2 在服务程序中使用SQL资源绑定

在服务程序中插入一个SQLDataSource变量。

对于EDT.7:

package services;
service SQLService
ds SQLDataSource?{ @Resource { bindingKey="Derby" } } ; // .7 syntax
end

对于EDT.8:

package services;

service SQLService
ds SQLDataSource?{ @Resource { uri="binding:Derby" } } ; // .8 syntax
end

该语法将服务导向与服务项目相关联的部署描述文件中定义为资源的“Derby”绑定类型。


6.3 处理SQL异常

SQL操作可能会因为许多原因失败。在我们的简单例子中,我们的服务能够捕获所有的SQL异常并且记录到服务器端的日志,然后再将该异常到服务客户端。它同样也会记录每次服务调用。

同样在end语句前复制粘贴所有这些服务程序的日志记录函数。

logActiveboolean = true;
activeServicestring;
private functionlogEntry(serviceFunction string in)
activeService = serviceFunction;
log("Entry: SQLService, " + serviceFunction);
end
privatefunction logException(ex sqlException?)
accumulatedMessage string = "Exception: SQLService, " + activeService;
while(ex!= null)
accumulatedMessage = accumulatedMessage + ",SQLSTATE = " +
ex.SQLState + ", message = " +ex.message;
ex= ex.nextException;
end
log(accumulatedMessage);
throw newanyException{message = accumulatedMessage};
end
private functionlog(text string in)
if(logActive)
sysLib.writeStdOut(text);
end
end

6.4 添加一个Payment记录

在数据库中包含一个添加语句来向数据库插入一行新记录。

为了编码该函数:

  • 在EGL编辑器中,向SQLService.egl文件复制粘贴如下代码。

    function addPayment(newPayment paymentRec in)
    logEntry ("addPayment" ) ;
    try
    addnewPayment to ds ;
    onException(ex sqlException)
    logException(ex);
    end
    end

  • 在你继续前面您必须解决paymentRec记录类型的引用问题,您能够通过使用OrganizeImports功能自动创建import语句,或者右击编辑器中空白区域,然后点击EGLSource > Organize Import。

EGL 会在文件开始处添加如下语句:

import records.paymentRec;

现在引用的问题已经解决。您能够通过菜单或Ctrl-Shift-O快捷键方便的使 用该功能。

  • 保存文件(Ctrl-S),然后在光标处添加一个add语句,然后按键CTRL-1,并从弹出菜单中选择AddSQL Statement,这个特征会改变隐式的SQL语句add为嵌入的形式,这样你可以方便的按自己需要进行修改。

    function addPayment(newPayment paymentRec in)
    logEntry ("addPayment" ) ;
    try
    add newPayment to ds
    with#sql{
    insert into PAYMENT
    (CATEGORY, DESCRIPTION, AMOUNT, FIXED_PAYMENT, DUE_DATE,
    PAYEE_NAME, PAYEE_ADDRESS1, PAYEE_ADDRESS2)
    values
    (?, ?, ?, ?, ?, ?, ?, ?)
    };
    onException(ex sqlException)
    logException(ex);
    end
    end

注意到PAYMENT_ID字段并没有包含在表的记录类型当中。而record定义当中的@GeneratedValue注释则告诉EGLSQL生成器,不要显示的添加该列。


相关引用:

Help topic: add considerations for SQL

Help topic: functions

Help topic: import

Help topic: SQL dataaccess


6.5 读取所有数据库记录

getAllPayments函数会使用数组对象的get语句来读取表中所有记录,并存储到数组中。

编写该函数:

  • 在EGL编辑器中,在SQLService.egl文件的日志函数前复制粘贴如下代码:

    function getAllPayments() returns(paymentRec[])
    payments paymentRec[];
    logEntry("getAllPayments");
    try
    get payments from ds;
    onException(ex sqlException)
    logException(ex);
    end
    return(payments);
    end
    EGL get语句会生成一个SQLSELECT语句来获取所有的结果集。当您的 get语句目标是一个动态的记录数组时,EGL会在该记录数组中获取所有匹配的行记录,然后将每一个后续的行记录插入到数组的下一个元素。

  • 对于add语句,您也能将光标放置在该语句任何位置,然后按CNTL-1来看EGL使用的SQL语句,或者保存该默认语句后,再按照自己需要进行修改。

  • 保存文件。

相关引用

Help topic: getconsiderations for SQL


6.6 替换记录

editPayment函数会替换目前数据库中存在的行记录为一个新编辑过的版本。默认语句会将数据库中所有与新编记录关键字段相配的所有记录替换掉。关键字段是那些用@Id属性声明的字段(例如我们例子中payment_id的字段)。

要写该函数代码:

打开SQLService.egl文件,在EGL编辑器中logging函数前复制粘贴如下代码:

  function editPayment(chgPayment paymentRec in)
      logEntry("editPayment");
      try
          replace chgPayment to ds;
      onException(ex SQLException)
          logException(ex);
      end
  end

保存文件。

相关引用

Help topic: replace considerations for SQL


6.7 删除记录

删除记录会从数据库表中删除所有指定的记录。

要写该函数代码:

打开SQLService.egl文件,在EGL编辑器中logging函数前复制粘贴如下代码:

function deletePayment(delPayment paymentRec in)
logEntry("deletePayment");
try
delete delPayment from ds;
onException(exSQLException)
if(ex.SQLState != "02000") // sql state is five digits
logException(ex);
end
end
end

  • EGL delete语句生成一个SQLDELETE语句,如果没有行记录,则Derby数据库会返回一个值为”02000“的SQLState,EGL运行时代码会抛出一个函数可以捕捉到的异常,及onException的逻辑。

  • 当函数捕捉到异常,却忽略其时,进程会继续运行而无中断。当SQLState值为”02000“时,同样也适用于前面的法则。当一个函数使用throw语句来抛出一个异常时,异常仍旧有效。

  • 在运行时,如果一个服务并不捕获异常,那么服务请求者会收到一个ServiceInovationException类型的异常。如果服务偶尔无法访问,那么根据错误的内容,请求者会收到一个类型为ServiceInvocationException或者ServiceBindingException类型的异常。

  • 保存文件。

相关引用

Help topic: Delete considerations for SQL

Help topic: Exception handling


6.8 创建测试数据

createDefaultTable函数会创建一系列数据来测试你完成的应用。

要写该函数代码:

打开SQLService.egl文件,在EGL编辑器中logging函数前复制粘贴如下代码:

function createDefaultTable() returns(paymentRec[])
payments paymentRec[];
logEntry("createDefaultTable");
try
try
execute from ds
with #sql{
delete from PAYMENT
};
onException(ex SQLException)
if(ex.SQLState != "02000") // sqlState is five digits
throw ex;
end
end
ispDate date= dateTimeLib.dateFromGregorian(20140405);
addPayment(new paymentRec{category = 1, description = "Apartment"
,amount = 880, fixedPayment = yes, dueDate = new date
,payeeName = "A Jones", payeeAddress1 = "100 Jones Dr"
,payeeAddress2 = "Jonesboro, NC"
});
addPayment(new paymentRec{category = 2, description = "Groceries"
,amount = 450, fixedPayment = no, dueDate = new date
,payeeName = "B Jones", payeeAddress1 = "200 Jones Dr"
,payeeAddress2 = "Jonesboro, NC"
});
addPayment(new paymentRec{category = 5, description = "ISP"
,amount = 19.99, fixedPayment = no, dueDate = ispDate
,payeeName = "C Jones", payeeAddress1 = "300 Jones Dr"
,payeeAddress2 = "Jonesboro, NC"
});
payments =getAllPayments();
onException(ex anyException)
logException(ex);
end
return(payments);
end 

代码按如下逻辑运行:

  • EGL的execute语句会运行一个SQL语句文法来删除PAYMENT表中所有记录。

  • IspDate变量会收到一个从dateTimeLib.dateValueFromGregorian()系统函数返回值,变量内容是适合数据库插入到dueDate字段的格式。

  • AddPayment函数会重复条用来插入新记录到PAYMENT表。

  • GetAllPayments函数会返回一个从PAYMENT表中读取的记录数组。

  • 按下CTRL-SHIFT-F来格式化你的代码,如果你见到红色的X,则请与我们在本课的样例代码(http://wiki.eclipse.org/EDT:Tutorial:_RUI_With_DataBase_Lesson_6_Code)进行比较。

  • 保存后关闭该文件。

相关引用

  • Help topic: execute considerations for SQL

  • Help topic: dateValueFromGregorian()


6.9 课程要点

您在本课程中已经完成了如下任务

添加一个嵌入式的SQL代码到程序并进行修改。

自动创建并组织import语句。

下节课,您将会创建一个widget来保存所有消费的数据。


第7课 创建可重用函数库


创建一个库来格式化钱的值,并将其与一个类别符号进行关联。该库将会包含使用在多个地方的函数、常量与变量。

当你引用从其他服务或者handler的逻辑中的声明时,您能够包含库的名称为前缀,例如,库的名称是MyLibrary,则MyLibrary.myLibraryVariable是合适的,库包含有myLibraryVariable变量。另外,您也可以使用use语句来包含库名称,这样就能避免在每处使用是都需要指出引用名称,如前面就可以之间使用myLibraryVariable来引用该变量。


7.1 创建一个

要创建一个库:

  • 右击PaymentClient文件夹,点击New> Library;

  • 在NewEGL Library窗口,输入如下信息:

  • 在EGLsource fil name字段,输入名称PaymentLib;

  • 在package字段,输入名称libraries;

  • 在EGLLibrary Type,选择默认值Basic;

这样,新库将在EGL编辑器中打开。

  • 将新的库文件样本代码替换成如下形式:

    package libraries;
    library PaymentLib{}
    end

  • 保存文件。


7.2 创建分类数组

在最后的end语句前添加如下代码:值是一个数组,像所有EGL数组一样,第一个元素的引用是1,而非0。

categories string[] =[
"Rent", // 1
"Food", // 2
"Entertainment", // 3
"Automotive", // 4
"Utilities", // 5
"Clothes", // 6
"Other" // 7
];
数组使用的逻辑如下:

在数据库中将花费的分类存储为整数形式以节省空间。

在web页面将花费的分类显示为字符串形式以清晰表明其意。


7.3 创建获取分类的get函数

下一个函数将会在花费分类的两种格式间进行转换:integer和string。

在最后的end语句前添加如下代码:输入花费分类的整数形式到函数,则返回对应的数组元素。如果输入时0,则函数返回一个空字符串。

function getCategoryDesc(cat int in) returns(string)
if(cat !=0) // the integer is not 0
return(categories[cat]);
else
return("");
end
end
在最后的end语句前添加如下代码:输入花费分类的字符串形式,则返回对应的整数形式值,如果没找到对应的匹配,则函数返回0。

function getCategoryNum(desc string in) returns(int)
for(i intfrom 1 to categories.getSize())
if(categories[i] == desc)
return(i);
end
end
return(0);	// no match
end

7.4 保存你的变化

要完成payment库的代码:

  1. 重新格式化处理文件;

  2. 保存并关闭PaymentLib,如果您在源文件中看到错误符号,则将其与本课程的代码http://wiki.eclipse.org/EDT:Tutorial:_RUI_With_DataBase_Lesson_7_Code进行比较。


7.5 课程要点

您已经学会了如何完成如下任务:

  • 创建一个库;

  • 添加函数与变量到库;


第8课 添加变量与函数到RUI Handler


添加支持用户界面逻辑的源代码。在第8课与第9课件,您将直接更新EGL源代码并检查Preview标签的变化。


8.1 添加支持DataGrid控件的代码

有两个目的来修改DataGrid控件的声明:当用户选择一个单元来对反应网页变化,确保网格输出能够正确的格式化。

  1. 在projectExplorer中,打开PaymentClient> EGLSource > handlers 然后双击PaymentFileMaintenance.egl;

  2. 点击源代码标签;

应用如下变化,忽略错误标记:

在allPayments_uiDataGrid控件声明中,在columns属性前添加如下代码:

selectionListeners::= cellClicked,
在selectionListeners属性指定一个或多个用户选择网格单元时的回调函数。您将添加一个函数到已经存在的数组。您将在稍后编写cellClicked函数。

函数中的格式化器是那些修改DataGrid控件中列显示的函数。为了展示该特性,先找到DataGridColumn中类型列声明,确保用户能够看到类型的名称描述,而非数字,添加width=90的代码。

, formatters = [formatCategory ]

当你在列中显示美元数量时,你需要将值 靠右对齐 ,完成 靠右对齐显示 并不需要编码,只需要在数量选项后添加如下代码。

, alignment =DataGridLib.ALIGN_RIGHT
allPayments_ui声明如下,添加有cellClicked和formatCategory错误标记。
allPayments_uiDataGrid{
layoutData =new GridLayoutData{
row = 2, column = 1,
verticalAlignment = GridLayoutLib.VALIGN_TOP},
selectionListeners ::= cellClicked,
columns =[
new DataGridColumn{name = "category", displayName = "Type",
width = 90, formatters = [ formatCategory ]},
new DataGridColumn{name = "description", displayName ="Description",
width = 120},
new DataGridColumn{name = "amount", displayName = "Amountdue",
width = 90, alignment = DataGridLib.ALIGN_RIGHT}
],
data =allPayments as any[],
selectionMode = DataGridLib.SINGLE_SELECTION};
在进行下一步前保存文件。


8.2 编写用户点击DataGrid控件的响应代码

当用户点击DataGrid控件时,cellClicked函数被调用。

在start函数下,添加如下代码:

function cellClicked(myGrid DataGrid in)
selectedPayment= allPayments_ui.getSelection()[1] as paymentRec;
selectedPayment_form.publish();
end
首先,cellClicked函数更新DataGrid 控件 中selectedPayment行记录,该行记录不只包括显示给用户的数据字段。在该应用中,DataGrid 控件 的每行记录对应于数据库的每一行数据。

其次,publish函数会造成selectedPayment与selectedPayment_ui布局数据的传输,当您在网页右端创建了一个单记录布局selectedPayment_ui时,您便可以调用该函数。您能跟踪如下关系:

表单管理器声明包含字段;

每个表字段引用一个控制器声明;

控制器声明关联一个模型到视图,selectedPayment记录的一个字段关联到一个selectedPayment_ui布局的一个子元素;

表单管理器有许多好处,这也对控制器集合至关重要。

还有两个其它关键问题:中括号数组索引的使用(如【1】),以及as操作符的使用:

  1. getSelection函数总是返回DataGrid控件data数组的行记录子集,然而,当你声明DataGrid控件时,您能通过指定如下设置来使用户一次只能选择一行记录:selectionMode=DataGridLib.SINGLE_SELECTION,当用户只能选择一行记录时,只有得到一个元素。

  2. 由getSelection函数返回的数组中每个元素都是ANY类型。您能通过使用Record类型来处理到网格中的输入和从网格返回的输出,在本教程中,Record类型是paymentRec,Record类型有如下用户:

要将数组元素赋值到DataGrid控件的data属性可以参照如下代码

data = allPaymentsas any[]
若要转换每个由DataGrid 控件 getSelection函数返回的数组元素,可以按如下所示进行:

allPayments_ui.getSelection()[1] as paymentRec
在每种情况下,as语句提供如下必要的转换。


8.3 网格中格式化列值

要添加如下格式化函数:

在文件end语句前添加如下代码

function formatCategory(class string inout, value string inout, rowData any in)
value =PaymentLib.getCategoryDesc(value as INT);
end
格式化 方法 有如上所示的参数,这种情况下,格式化 方法 能将您先前创建的 库函数进行包装。

按下Ctrl-Shift-O来组织需要的import语句,保存文件。所有的错误标记符号将消失。

测试DataGrid控件的格式转换以及每行数据的正确显示

您能在访问数据库前测试最近的这些变化。

点击Preview标签,注意到分类现在都为文字描述(例如,显示Rent而非数字1)

点击DataGrid控件中每一个行记录,可以发现每行记录布局都进行了对应的更新,然而格式化器只影响DataGrid控件,其Description描述字段则包含有数字。本教程后面将会处理该问题。

点击源代码标签,修改start函数,这样原型数据的第一条记录将包含有一个payeeName,它是DataGrid中未显示的paymentRec记录字段。

function start()
allPayments_ui.data =[
new paymentRec{
category =1, description = "test01", amount = 100.00
, payeeName= "Someone" },
new paymentRec{category = 2, description = "test02", amount =200.00},
new paymentRec{category = 3, description = "test03", amount =300.00}];
end
点击Preview标签,然后点击DataGrid 控件 的第一行。

如上所示,您能在RichUI编辑器中快速的从一个标签切换到另外一个来测试一些微小的变化。


8.4 注释原型数据

如下步骤所示,您能够快速的注释或取消代码注释。

点击源代码标签。

在start函数下选择completeassignment statement,右击所选区域,选择EGLSource> Toggle Comment。


现在每行开始处均有注释符号,您能通过选择要注释的语句,重复如上步骤来移除注释。同时,EGL也支持使用能够星号与斜杠(/*)符号来进行注释,如下所示。

/*
You can add comments in either of two ways.
*/


8.5 声明一个服务访问的变量

您能声明一个服务访问的变量,它让您与先前定义的服务进行通讯。

要创建如下变量,首先确定您安装EDT版本,Help->About Eclipse IDE for EGL Web Developers->Installation Details,查看EGLWeb Developer Tools行Version字段值,

然后按照安装版本选择对于的服务变量使用语法,在EGL源代码顶端,找到处理器PaymentFileMaintenance声明,添加一个空行,然后在uiGridLayout声明前添加如下语句:

  • 若为EDT 7.0,添加为:

    dbService SQLService?{@dedicatedService};

    @dedicatedService属性指出正在引用的服务是一个将部署在RichUI Handler的专属服务。

  • 若为EDT 8.0,添加为 :
 dbService SQLService? ;
 dbServiceBinding HTTPProxy ;

如果显示的边界区域出现红色X,则可以把鼠标移动到X上查看错误消息。

  • 我们可以通过按下Ctrl+Shift+O来解决unresolvedtype错误,新的import语句会提供到service包的访问,如PaymentService项目中的SQLService服务类型,由于其是在PaymentClient项目的build路径中,所以该引用问题能够解决。

  • 保存文件。


8.6 创建函数使用服务访问变量来调用服务

您现在创建了几个函数来调用不同独享服务中的函数。一旦您理解如何设置调用,其它都非常简单。

首先,在最后的end语句前添加一个服务异常处理handler,它包含有如下代码:

function serviceExceptionHandler(ex anyException)
sysLib.writeStderr("Failure: " + ex.message);
if (ex isaServiceInvocationException)
sysLib.writeStderr("Detail 1: " +
(ex asServiceInvocationException).detail1);
sysLib.writeStderr("Detail 2: " +
(ex asServiceInvocationException).detail2);
sysLib.writeStderr("Detail 3: " +
(ex asServiceInvocationException).detail3);
end
end
然后从表中包含读取数据的函数。在 cellClicked 函数后添加一个空白行:

如果您安装的为EDT0.7,则添加如下代码

function readFromTable()
calldbService.getAllPayments() returning to updateAll
onException serviceExceptionHandler;
end

如果安装的为EDT0.8,则添加如下代码

  function readFromTable()
     call dbService.getAllPayments() 
        using new HttpProxy
        returning to updateAll
        onException serviceExceptionHandler;
  end

注意:

EDT 0.8中dedicatedService用法已经被新的HttpRroxy语法取代,新语法为:

(1)如果为引用服务,则不需要指定实现的变量名调用服务
    call MyService.functionName() using new HttpProxy returning to handleResponse onException serviceExceptionHandler;
(2)如果为引用接口,则必须指定实现的变量名调用服务
    http HttpProxy = new HttpProxy("server.MyService");
    call IMyService.functionName() using http returning to handleResponse onException serviceExceptionHandler;

RichUI中的call语句是一个只能用于访问服务的用法,它在运行时的通讯是异步的,即在服务响应的时候,用户仍然能够继续与handler处理器进行交互。

异步call语句的用法在如下两个函数中使用:

updateAll
serviceExceptionHandler
以上两个函数在服务响应或失败后被EGL运行时代码调用。如果服务响应成功,则updateAll函数被调用。如果调用失败,则EGL运行时代码会调用名为serviceExceptionHandler的函数。

该例子的异常handler会将文本写到Eclipse控制台或者标准错误输出设备。这种处理响应非常适合开发阶段或者产品原型阶段,如果要运用于产品级环境的代码,则您需要根据您特定情况来谨慎考虑异常处理的需求。

现在,在call语句的任意位置点击,然后按下Ctrl-1,则会创建updateAll回调函数。


在弹出窗口点击Create函数来在您的程序中添加一个空白的函数,EGL会提供给您一个空的updateAll函数,而如果您程序中也没有包含一个叫serviceExceptionHandler的程序,则一个异常错误处理器也会为您创建。

在updateAll函数中创建的参数列表是服务中期待的返回值类型。如下是RichUI编辑器的表现行为:

  • 由于服务类型中的getAllPayments函数在编辑器中有定义,所以回调函数的参数列表则是正确的;

  • 该函数当前仅当您在前一步解决了名称为SQLService类型解析问题才可用;

下一步,您将创建添加如下样例数据的函数。点击Ctrl-F来打开Find/Replace对话框,输入SampleData,点击Find,更sampleData函数,则代码如下:

function sampleData(event Event in)
calldbService.createDefaultTable() returning to updateAll
onException serviceExceptionHandler;
end
您并没有使用前面提到的方法来创建回调函数,因为该回调函数已经存在。

下一步,您将创建添加数据的函数。更新addRow函数,这样代码如下所示:

function addRow(event Event in)
calldbService.addPayment(new paymentRec) returning to recordAdded
onException serviceExceptionHandler;
end
现在在call语句中任意位置点击,按下Ctrl-1来创建一个空白的回调函数。在弹出窗口中点击Createfunction来包含recordAdded函数。

现在创建删除数据的函数。更新deleteRow函数,代码如下:

function deleteRow(event Event in)
for(i INT from1 to allPayments.getSize())
if(allPayments[i].paymentID == selectedPayment.paymentID)
allPayments.removeElement(i);
exit for;
end
end
calldbService.deletePayment(selectedPayment) returning to recordRevised
onException serviceExceptionHandler;
end
该函数执行如下功能:

  • 从局部的记录数组删除选定的行记录;

  • 调用数据库服务来从数据库中删除行记录;

现在在call语句中任意位置点击,按下Ctrl-1来创建一个空白的回调函数,在弹出窗口中中点击Createfunction来自动创建recordRevised函数。

要完成本步骤:

  • 按下Ctrl-Shif-F来格式化您的代码;

  • 保存文件;

相关信息

Help Topic:从富用户界面应用中异步调用服务。


8.7 更新start函数来使用数据库中行记录初始化DataGrid控件

在start函数的end语句前添加如下代码来初始化DataGrid控件

readFromTable();
虽然您已经将readFromTable函数正确的在onConstructionFunction中使用,我们仍建议您将start函数设计为一个独立逻辑单元,这样以防止您以后决定在web网页渲染前添加其它的代码。

保留start函数中注释掉的代码,防止您在不能访问数据库的时候需要调试web网页,您能通过在富用户界面编辑器中注释与否来快速在是否是使用原型数据中进行切换。


8.8 完成回调函数

您现在完成如下自动为您创建的回调函数。

  • UpdateAll

  • recordAdded

  • recordRevised

其中updateAll函数从独享服务中接受一个paymentRec记录数组,该函数按如下方式进行调用:

  • 作为回调函数,该函数在启动时readFromTable调用服务后调用;

  • 作为回调函数,当用户点击Sample按钮来调用sampleData函数时调用;

按如下更新updateAll函数代码:

function updateAll(retResult paymentRec[] in)
allPayments =retResult;
allPayments_ui.data = allPayments as any[];
end
函数从服务中接受数据,然后用其更新全局的payment记录数组,再刷新数据网格。

ReadAdded则接收服务函数addPayment返回的记录,将该函数更新为如下代码:

function recordAdded()
readFromTable();
end
函数readFromTable会从数据库中读取所有行记录,这样Data Grid 存储的数据将会把新记录行数据包含进来,如数据库自动生成的paymentID值,否则DataGrid将无法获取这些数据。

ReadRevised则接收服务函数addPayment返回的记录,将该函数更新为如下代码:

function recordRevised()
allPayments_ui.data = allPayments as any[];
end

函数将刷新DataGrid 控件

重新格式化您的代码,保存文件。如果在您的源代码文件中看到错误符号,可以将您的源代码与我们在本课程的代码进行对比(http://wiki.eclipse.org/EDT:Tutorial:_RUI_With_DataBase_Lesson_8_Code)。


8.9 测试界面

预览您的工作,现在您将可以访问数据库。

  1. 点击Preview标签。由于您注释掉了原型数据,现在DataGrid没有数据,并且数据库也没有行记录。

  2. 点击Sample按钮来创建样例数据。

  3. 如果EGL请求数据,则在UserId与Password字段分别输入admin,选择Remembermy user ID...,然后点击OK。


如果您在完成教程前重启了工作空间,那么这个窗口将会在您下次访问数据库的时候出现。最后,DataGrid会重显示如下样例数据。


    4. 点击Add按钮,一个带有默认值的新行会添加到数据网格的底端。


    5. 选择Apartment行,然后点击Delete,则该行记录会从后台数据库与前端显示中删除掉。


点击数据网格第一行,数据网格中从数据库获取的数据会传输到单记录布局。注意Key字段的值会反映有多少行记录添加到数据库,并且可能并不匹配您网页上的值。


8.10 课程要点

您已经学习如何完成如下任务:

  • 创建格式化函数;

  • 响应用户在DataGrid的选择操作

  • 将数据从DatGrid传输到GridLayout;

  • 注释与取消代码注释;

  • 从RichUI应用中访问服务;

下节课程,您将完成RichUI Handler代码。


上一篇:使用EGL Rich UI访问数据库(1-4课)下一篇:使用EGL Rich UI访问数据库(9课-12课)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值