2012-11-20 56 views
3

我有關於ADF Faces表格和動態區域的問題。ADF af:表格恢復表狀態

前提條件:
了Oracle JDeveloper 11.1.1.6.0

我使用ADF Faces和ADF綁定層來顯示的Java POJO中的AF列表:表。 ADF表顯示在有界任務流中的視圖中。
此任務流在另一個視圖的動態區域中使用。
導航包含兩個鏈接,這些鏈接用於通過bean屬性進行選擇,該屬性限定要在動態區域中顯示的任務流。
動態區域通過任務流綁定接收「輸入參數映射」。
該映射包含要在表中顯示的POJO和一個狀態Bean,該狀態Bean應該保存位於視圖上的其他組件的表狀態和狀態(請參閱下面的實現)。

問題/要求:

1.預選:

預選的單個行中根據包含在上表中的第一負載的POJO數據的表。

2.保持在選擇任務流開關:

在該表(界任務流A)所選擇的行還應該切換到另一任務流有界B和回到A(其中表所在之後,可選擇)。

3.無MDS

保存點/ MDS功能沒有使用。

4.一致表模型和綁定層

它應該能夠在任務流之間的切換之後,選擇表中的元素之後詢問表組件和所選擇的行的結合。
切換任務流後,在選擇表格中的元素後,表格行和綁定中的選定行應保持一致。

已經嘗試過:

預選一排,並保持在選擇任務流開關不使用MDS /保存點。

我已經綁定了一些表屬性到「狀態」bean。 下面附加了bean的實現。

1.表的屬性:

選擇行鍵:
selectedRowKeys =「#{pageFlowScope.stateBean.tableStateBean。rowKeySet} 「

支持bean屬性綁定RichTable:
結合= 」#{pageFlowScope.stateBean.tableStateBean.richTable}「

默認選擇監聽
SelectionListener中=」 #{綁定.postanschriften.collectionModel.makeCurrent}」

我們試圖在這裏:
在表的初始加載和更改RO調用w bean方法getRowKeySet(..)。
在此方法中,要在初始表格加載(this.rowKeySet == null)上計算要選擇的行。 由於表屬性selectedRowKeys綁定到pageFlowScope.stateBean.tableStateBean.rowKeySet,如果在表中選擇了另一行,則更新該bean中的屬性。 如果我們將任務流從A更改爲B,反之亦然,則調用backing bean屬性richTable的getter。在getter方法中,選擇狀態被恢復。

2.執行「狀態」豆的:

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

設置一個 '選擇' 行是相當容易的。 有幾種解決方案。 這只是其中之一: 爲您的表格綁定到您的支持bean。 在吸氣添加以下代碼:

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); 
+0

嗨。我們希望在更改綁定到動態區域的任務流時保持表狀態。示例:加載任務流程A並預選行5.選擇行7.切換到任務流程B.返回到任務流程A.現在應選擇第7行。 – Max

+0

無論何時您更改任務流或定義具有特定範圍(根據您的用例)的託管bean(包含所選行/標識符),您都可以傳遞選定行的標識符。 – User404

+0

我們已經嘗試使用RowKeySet作爲標識符。但問題是在排序表時,包含的Key會發生變化。 – Max

0

你可能想查看您的應用程序設計。在具有單個任務流的兩個視圖活動(頁面片段)之間導航可能是更簡單的解決方案,而不是使用動態區域並在兩個任務流之間切換。你也寫了很多代碼來保存行選擇。您只需要爲所選行存儲唯一列的數據,並使用DCBinding Iterator在上面的文章中提供的邏輯將行選擇設置爲該行。