2010年4月19日星期一

ADF_072:Table 组件使用指南之二:基于Table的CRUD

本文最后一次修改时间:2012-03-16。
运行环境:JDeveloper 11.1.2.1.0 + Oracle Database 10g Express Edition 10.2.0.1。

1. 采用弹出窗口的方式来实现增加和修改功能
个人比较喜欢这种方式,感觉比较自然。
(1)页面效果

(2)增加功能
在当前行的上一行增加一条记录。

(3)修改功能
修改当前行记录。

(4)删除功能
删除当前行,删除前有提示。


2. 增加和修改功能实现说明
(1)点击增加或修改按钮都是弹出一个窗口,即popup组件

<af:commandButton text="CreateInsert" id="cbInsert">
<af:showPopupBehavior popupId="::popupEditOrInsert" triggerType="action" align="endAfter"/>
</af:commandButton>
<af:commandButton text="Edit" id="cbEdit">
<af:showPopupBehavior popupId="::popupEditOrInsert" triggerType="action" align="endAfter"/>
</af:commandButton>

说明:在按钮上添加了showPopupBehavior操作后,将屏蔽按钮上的action或actionListener事件,也就是说不会再触发action或actionListener事件。
如果想要触发并执行完按钮上的action或actionListener方法,然后再弹出popup窗口,只能在action或actionListener方法中用代码弹出popup窗口。比如:
FacesContext facesContext = FacesContext.getCurrentInstance();
ExtendedRenderKitService service =
Service.getRenderKitService(facesContext, ExtendedRenderKitService.class);
service.addScript(facesContext, "AdfPage.PAGE.findComponent('popupDelete').show();");

(2)popup组件的代码
重要的属性说明如下:
contentDelivery="lazyUncached",因为每次弹出的内容都不同,因此不要Cache。
popupFetchListener,是popup组件窗口弹出时调用的方法。
popupCanceledListener,是关闭popup组件窗口时调用的方法,比如点击右上角的X关闭窗口。
dialogListener,负责监听用户点击了OK/Cancel按钮。
Form中绑定的Data Control和Table中绑定的Data Control一样。
                    
<af:popup id="popupEditOrInsert" contentDelivery="lazyUncached" childCreation="deferred"
autoCancel="disabled"
popupFetchListener="#{backingBeanScope.myBackingBean.editOrInsertPopupFetchListener}"
popupCanceledListener="#{backingBeanScope.myBackingBean.editOrInsertPopupCancelListener}">
<af:dialog id="dialogEditOrInsert" title="Edit or Insert" type="okCancel"
dialogListener="#{backingBeanScope.myBackingBean.editOrInsertDialogListener}">
<f:facet name="buttonBar"/>
<af:panelFormLayout id="pfl1">
<af:inputText value="#{bindings.JobId.inputValue}" label="#{bindings.JobId.hints.label}"
required="#{bindings.JobId.hints.mandatory}"
columns="#{bindings.JobId.hints.displayWidth}"
maximumLength="#{bindings.JobId.hints.precision}"
shortDesc="#{bindings.JobId.hints.tooltip}" id="it1">
<f:validator binding="#{bindings.JobId.validator}"/>
</af:inputText>
......
</af:panelFormLayout>
</af:dialog>
</af:popup>

(3)还有很重要的一点是,为panelCollection设置partialTriggers,指向popup组件id和dialog组件id。
这样无论是确定还是取消操作,都会局部刷新panelCollection,进而刷新Table。
<af:panelCollection id="pc1" partialTriggers="::popupEditOrInsert ::dialogEditOrInsert">

3. 双击某行,弹出修改窗口
双击弹出修改窗口,是一个比较常见的功能,在这里我使用af:clientListener + af:serverListener 方式实现。
(1)clientListener
<af:clientListener method="doubleClickOnTable" type="dblClick"/>
(2)serverListener
<af:serverListener type="TableDoubleClickEvent"
method="#{backingBeanScope.myBackingBean.handleTableDoubleClick}"/>
(3)clientListener调用的javascript函数
<af:resource type="javascript" source="js/table_function.js"/>
其中包含doubleClickOnTable函数:

function doubleClickOnTable(evt) {
var table = evt.getSource();
AdfCustomEvent.queue(table, "TableDoubleClickEvent", {},true);
evt.cancel();
}

(1)(2)(3)组合在一起,实现了双击弹出修改窗口功能,原理如下:
当双击事件(dblClick)发生时,监听该事件的clientListener触发了javascript方法:doubleClickOnTable,该方法向事件队列中异步地(true参数表示异步,false表示同步)压入一个事件:TableDoubleClickEvent,监听该事件的serverListener触发了Managed Bean中的方法handleTableDoubleClick。

4. 删除功能实现说明
详细说明请参考《使用ADF实现基于Form的CRUD (2)》。

<af:commandButton text="Delete" disabled="#{!bindings.Delete.enabled}" id="cbDelete">
<af:showPopupBehavior popupId="popupDelete" triggerType="action" align="endAfter"/>
</af:commandButton>
<af:popup childCreation="deferred" autoCancel="disabled" id="popupDelete">
<af:dialog id="dialogDelete" title="Confirm Delete"
dialogListener="#{backingBeanScope.myBackingBean.deleteDialogListener}">
<f:facet name="buttonBar"/>
<af:outputText value="The record will be deleted, are you sure?" id="ot5"/>
</af:dialog>
</af:popup>


5. Managed Bean完整代码

package view;

import javax.faces.context.FacesContext;

import oracle.adf.model.BindingContext;
import oracle.adf.view.rich.event.DialogEvent;

import oracle.adf.view.rich.event.PopupCanceledEvent;
import oracle.adf.view.rich.event.PopupFetchEvent;

import oracle.adf.view.rich.render.ClientEvent;

import oracle.binding.BindingContainer;
import oracle.binding.OperationBinding;

import org.apache.myfaces.trinidad.render.ExtendedRenderKitService;
import org.apache.myfaces.trinidad.util.Service;

import view.util.ADFUtils;

public class MyBackingBean {
public MyBackingBean() {
super();
}

public void editOrInsertDialogListener(DialogEvent dialogEvent) {
if (dialogEvent.getOutcome().equals(DialogEvent.Outcome.ok)) {
OperationBinding operb = ADFUtils.findOperation("Commit");
operb.execute();
} else {
OperationBinding operb = ADFUtils.findOperation("Rollback");
operb.execute();
}
}

public void editOrInsertPopupFetchListener(PopupFetchEvent popupFetchEvent) {
if (popupFetchEvent.getLaunchSourceClientId() != null) {
if (popupFetchEvent.getLaunchSourceClientId().contains("cbInsert")) {
OperationBinding operb = ADFUtils.findOperation("CreateInsert");
operb.execute();
}
}
}

public void editOrInsertPopupCancelListener(PopupCanceledEvent popupCanceledEvent) {
OperationBinding operb = ADFUtils.findOperation("Rollback");
operb.execute();
}

public void deleteDialogListener(DialogEvent dialogEvent) {
if (dialogEvent.getOutcome().equals(DialogEvent.Outcome.ok)) {
doDelete();
}
}

private void doDelete() {
OperationBinding operb = ADFUtils.findOperation("Delete");
Object result = operb.execute();
if (operb.getErrors().isEmpty()) {
operb = ADFUtils.findOperation("Commit");
operb.execute();
}
}

public void handleTableDoubleClick(ClientEvent clientEvent) {
FacesContext facesContext = FacesContext.getCurrentInstance();
ExtendedRenderKitService service = Service.getRenderKitService(facesContext, ExtendedRenderKitService.class);
service.addScript(facesContext, "AdfPage.PAGE.findComponent('popupEditOrInsert').show();");
}
}


Project 下载:ADF_Table_CRUD.7z

参考文献:
1. http://andrejusb.blogspot.com/2007/04/create-edit-and-delete-operations-in.html
2. http://andrejusb.blogspot.com/2007/11/jdeveloper-11g-create-edit-and-delete.html
3. http://andrejusb.blogspot.com/2009/11/crud-operations-in-oracle-adf-11g-table.html
4. http://andrejusb.blogspot.com/2009/11/crud-operations-in-jdeveloperadf-11g-r1.html
5. http://andrejusb.blogspot.com/2010/05/crud-operations-in-oracle-adf-11g-table.html

没有评论: