假设有这样的需求,在Table的第一列加入单选框,当用户对table中的某几行打勾后,点击页面按钮(假设提交按钮)。那么对应几行的状态都由New变成Confirm。
如上图,当点击Apply按钮后,打勾的行状态都变成confirm。
实现的方法有:
- 在点了apply后对所有的行循环一遍后选出打勾的行将状态set一下,但是这样子的方法是很没有效率的(假设有一万行,并且只选了一行)。
- 打开CHECKBOX上的FireAction,当点了这一行以后马上对该行状态进行处理(set好),当点了apply后就commit就可以了,这里需要注意的就是找到当前行以及点空后的处理。
所以优化的关键是如何根据打勾的行快速的在VO中找到对应的行并且对它进行操作。
一、打开CHECKBOX的FireAction
FireAction其实就是一个局部页面事件,对某个Item设置了FireAction后,当这个Item发生了状态的变化,那么就会触发页面事件,并且可以在CO中捕获到,而我们就可以在CO中捕获事件并作出相应的操作。这个选项在属性栏Client Action下:
Action Type | firePartialAction | ||
Event | Select | ||
Parameters |
| ||
Submit | True |
Event是用来标识页面事件的,一个页面上可能有多个页面事件,所以通过Event来标识到底是哪一个页面事件。
二、在CO中捕获Select事件
使用下列语句来实现
if(“Select”.equals(pageContext.getParameter(EVENT_PARAM))){
//Code…
}
Parameters为当页面事件发生的时候,同这个页面事件一起返回的参数,在CO中可以通过pageContext.getParameter(“RowId”)来获得上例中的参数。返回的参数(必须是唯一索引)是很重要的,因为需要用它寻找VO对应行的主键。
对有主键的VO,参数直接用KeyId就可以了,对于没有主键的VO,例如上例,需要在VO的sql中加入ROWID作为唯一索引,然后传进页面事件中。
import oracle.apps.fnd.framework.OAApplicationModule;
public void processFormRequest(OAPageContext pageContext, OAWebBean webBean)
{
super.processFormRequest(pageContext, webBean);
OAApplicationModule am = pageContext.getApplicationModule(webBean);
String rowId = pageContext.getParameter("RowId");
if("Select".equals(pageContext.getParameter(EVENT_PARAM))){
am.invokeMethod(“setSeelctRow”, new Serializable[] {rowId},
new Class[] {String.class});
}
}
三、在AM中,通过页面传入的参数得到当前行
import oracle.jbo.domain.RowID;
public void setSelectRow(String rowId){
LookupValueVOImpl vo = getLookupValueVO1();
RowID key = new RowID(rowId);
LookupValueVORowImpl row = (LookupValueVORowImpl)vo.getFirstFilteredRow("Rowid1", key);
row.setMeaning("Confirm");
}
需要注意的是因为我们例子中的VO是没有主键的,所以使用了RowId作为唯一索引,如果VO中是带有主键的,那么就用这个主键作为参数得到对应的行:
import oracle.jbo.domain.Number;
import oracle.apps.fnd.framework.OAException;
public void setSelectRow(String keyId){
LookupValueVOImpl vo = getLookupValueVO1();
try{
Number key = new Number(rowId);
}catch(Exception e){
throw new OAException(“Can not format key Id”);
}
LookupValueVORowImpl row = (LookupValueVORowImpl)vo.getFirstFilteredRow("KeyId", key);
row.setMeaning("Confirm");
}
vo.getFirstFilteredRow是VO自带的一个检索的方法,第一个参数是VO中对应字段的Id,第二个参数是需要比较的参数。
上面这种方法,在11i和12版中都可以使用,下面介绍的方法是通过页面自带的一个参数来得到当前行的。
import oracle.apps.fnd.framework.OAApplicationModule;
public void processFormRequest(OAPageContext pageContext, OAWebBean webBean)
{
super.processFormRequest(pageContext, webBean);
OAApplicationModule am = pageContext.getApplicationModule(webBean);
String rowIndex = pageContext.getParameter("EVENT_SOURCE_ROW_INDEX_PARAM");
if("Select".equals(pageContext.getParameter(EVENT_PARAM))){
am.invokeMethod(“setSeelctRow”, new Serializable[] { rowIndex },
new Class[] {String.class});
}
}
import oracle.jbo.domain.Number;
import oracle.apps.fnd.framework.OAException;
public void setSelectRow(String rowIndex){
LookupValueVOImpl vo = getLookupValueVO1();
int index = Integer.parseInt(rowIndex);
LookupValueVORowImpl row = (LookupValueVORowImpl)vo. getRowAtRangeIndex(index);
row.setMeaning("Confirm");
}
这种方法和之前使用的KeyId的区别在于它使用的当前页面的range索引,例如一个页面有10行数据,当我们对第五行打勾是,参数pageContext.getParameter(“EVENT_SOURCE_ROW_INDEX_PARAM”)返回4(从0开始计算)。
使用这个索引,在速度上会比前面的方法快一些,因为getFirstFilteredRow是从整个VO进行查找,而getRowAtRangeIndex是从一个Range中进行检索(如果一页10行,那么就从10条记录中检索)。
但是在12版中,EVENT_SOURCE_ROW_INDEX_PARAM被建议不使用,可能是有bug(我没发现-_-!!!),而用来替代的另外一个参数并不能得到我们需要的结果,所以这个方法在12版最好还是不要用的好。