我遇到有关ADF Faces表和动态区域的问题。
先决条件:
Oracle JDeveloper 11.1.1.6.0
我正在使用ADF Faces和ADF Binding层在af:table中显示Java POJO列表。
ADF表显示在有界任务流内的视图上。
此任务流用于另一个视图上的动态区域。
导航包含两个链接,用于通过bean属性进行选择,该属性限制任务流以在动态区域中显示。
动态区域通过任务流绑定接收“输入参数映射”。
此映射包含要在表中显示的POJO和一个state-Bean,它应该保存表状态和视图上可能存在的其他组件的状态(参见下面的实现)。
问题/要求:
1。预选:
在第一次加载表格时,根据POJO中包含的数据预选表格中的单行。
2。保持对任务流切换的选择:
在切换到另一个有界任务流B并返回到A(表所在的位置)之后,也应该选择表中的选定行(有界任务流A)。
第3。没有MDS
不使用保存点/ MDS功能。
4。一致的表模型和绑定层
在切换任务流之后和选择表中的元素之后,应该可以询问表组件和所选行的绑定。
在切换任务流之后和选择表中的元素之后,表格行和绑定中的选定行应该是一致的。
已经尝试过:
预选行并在不使用MDS /保存点的情况下保持对任务流程切换的选择。
我已经将一些表属性绑定到“状态”bean。 bean的实现如下。
1。表的属性:
所选行键:
selectedRowKeys = “#{pageFlowScope.stateBean.tableStateBean.rowKeySet}”
绑定RichTable的Backing-Bean属性:
binding =“#{pageFlowScope.stateBean.tableStateBean.richTable}”
默认选择监听器
SelectionListener中= “#{bindings.postanschriften.collectionModel.makeCurrent}”
我们在这里尝试了什么:
在初始加载表并更改行bean方法时,调用getRowKeySet(..)。
在此方法中,要在初始表加载时计算要选择的行(this.rowKeySet == null)。
因为table属性selectedRowKeys绑定到pageFlowScope.stateBean.tableStateBean.rowKeySet
,如果在表中选择了另一行,则更新bean中的属性。
如果我们将任务流从A更改为B,反之亦然,则调用支持bean属性richTable的getter。在getter方法中,恢复选择状态。
2。 “状态”bean的实现:
public class TableStateBean {
private RichTable richTable;
private RowKeySet rowKeySet;
private String bindingIteratorName;
private RowMatcher matcher;
public RowKeySet getRowKeySet() {
if (this.rowKeySet == null) {
preselectRow();
}
return rowKeySet;
}
public RichTable getRichTable() {
if (richTable != null && rowKeySet != null) {
RowKeySet currentTableSelection = getCurrentTableSelection();
RowKeySet tableSelectionToRestore = getTableSelectionToRestore();
executeSelection(tableSelectionToRestore, currentTableSelection);
}
return richTable;
}
public void setRichTable(RichTable pRichTable) {
richTable = pRichTable;
}
public void doTableSelection(){
preselectRow();
}
private RowKeySet getCurrentTableSelection() {
Row currentRow = (Row) JSFUtils.resolveExpression("#{bindings." + this.bindingIteratorName + ".currentRow}");
Key currKey = currentRow.getKey();
ArrayList<Key> lst = new ArrayList<Key>(1);
lst.add(currKey);
RowKeySet keySet = new RowKeySetImpl();
keySet.add(lst);
return keySet;
}
private RowKeySet getTableSelectionToRestore() {
RowKeySet tableSelectionToRestoreRow = null;
RowSetIterator rowSetIterator = extractRowSetIterator();
int tableRowIndexOfCurrentSelectedKey = getSingleRowKeyIndexValue(this.rowKeySet);
if (tableRowIndexOfCurrentSelectedKey != -1) {
Row currentRow = rowSetIterator.first();
for (int i = 0; rowSetIterator.hasNext() && i < tableRowIndexOfCurrentSelectedKey; i++) {
currentRow = rowSetIterator.next();
}
if (currentRow != null) {
Key newSelectionKey = currentRow.getKey();
ArrayList<Key> keyList = new ArrayList<Key>(1);
keyList.add(newSelectionKey);
tableSelectionToRestoreRow = new RowKeySetImpl();
tableSelectionToRestoreRow.add(keyList);
}
}
return tableSelectionToRestoreRow;
}
private int getSingleRowKeyIndexValue(RowKeySet rowKeySet) {
int tableRowIndexOfCurrentSelectedKey = -1;
if (rowKeySet != null) {
Object[] rowKeySetArray = rowKeySet.toArray();
List<Key> selectedRowKeys = (rowKeySetArray.length > 0) ? (List<Key>) rowKeySetArray[0] : new ArrayList<Key>();
if (selectedRowKeys.size() > 0) {
Key currentSelectedKey = selectedRowKeys.get(0);
Object[] attributeValues = currentSelectedKey.getAttributeValues();
assert (attributeValues.length > 0);
tableRowIndexOfCurrentSelectedKey = (Integer) attributeValues[0];
}
}
return tableRowIndexOfCurrentSelectedKey;
}
private void executeSelection(RowKeySet newCurrentRow, RowKeySet oldCurrentRow) {
SelectionEvent selectionEvent = new SelectionEvent(oldCurrentRow, newCurrentRow, richTable);
selectionEvent.queue();
AdfFacesContext.getCurrentInstance().addPartialTarget(richTable);
}
protected void preselectRow() {
RowSetIterator rowSetIterator = extractRowSetIterator();
RowKeySet oldSelection = getCurrentTableSelection();
Row currentRow = rowSetIterator.first();
while (rowSetIterator.hasNext()
&& (!matcher.match(currentRow))) // Matcher selects which row should be displayed according to the Object bound behind the binding-layer.
{
currentRow = rowSetIterator.next();
}
if (currentRow != null) {
Key key = currentRow.getKey();
RowKeySet newSelection = createRowKeySet(key);
setActiveRowKey(key);
executeSelection(newSelection, oldSelection);
setRowKeySet(newSelection);
}
}
private void setActiveRowKey(Key pKey) {
ArrayList<Key> lst = new ArrayList<Key>(1);
lst.add(pKey);
this.richTable.setActiveRowKey(lst);
}
private RowKeySet createRowKeySet(Key pKey) {
ArrayList<Key> lst = new ArrayList<Key>(1);
lst.add(pKey);
RowKeySetImpl rowKeySetToCreate = new RowKeySetImpl();
rowKeySetToCreate.add(lst);
return rowKeySetToCreate;
}
private RowSetIterator extractRowSetIterator() {
DCIteratorBinding iteratorBinding = ADFUtils.findIterator(this.bindingIteratorName);
RowSetIterator rowSetIterator = iteratorBinding.getRowSetIterator();
return rowSetIterator;
}
}
在某些情况下,绑定层似乎与RichTable组件上选择的元素不同步。所以我猜上面提到的解决方案不是很强大。
是否有其他方式以健壮的方式存档上述功能? 我认为根据绑定POJO中的某些值预先选择表中的一行并不是那么奇怪。 并且在有界任务流(动态区域)之间切换后保留表的选定行应该是可能的,不是吗?
感谢您的帮助
此致
最高
答案 0 :(得分:0)
设置“选定”行非常简单。 有几种解决方案。 这只是其中之一: 为您的表创建一个绑定到您的支持bean。 在getter中添加以下代码:
DCBindingContainer bindings = (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
DCIteratorBinding dcItteratorBindings =
bindings.findIteratorBinding("yourViewObjectIterator");
RowSetIterator it = dcItteratorBindings.getRowSetIterator();
Rows[] rows = voTableData.getAllRowsInRange();
Row needsSelection = null;
for(Row r: rows)
{
//just search for the row you want to set selected
if(r.getAttribute("SomeAttribute").eqauls(..))
needsSelection = r;
}
if(needsSelection != null)
it.setCurrentRow(needsSelection);
答案 1 :(得分:0)
您可能想要查看您的应用程序设计。使用单个任务流在两个视图活动(页面片段)之间导航可能是更简单的解决方案,而不是使用动态区域和在两个任务流之间切换。你也写了很多代码来保持行选择。您只需要存储所选行的唯一列的数据,并使用DCBinding Iterator在上面的帖子中提供逻辑,将行选择设置为该行。