3

ADFFacesテーブルと動的領域に関して問題があります。

前提条件:
Oracle JDeveloper 11.1.1.6.0

ADFフェイスとADFバインディングレイヤーを使用して、Java POJOのリストをaf:tableに表示しています。ADFテーブルは、制限されたタスクフロー内のビューに表示されます。
このタスクフローは、別のビューの動的領域で使用されます。
ナビゲーションには、動的領域に表示するタスクフローを制限するBeanプロパティを介して選択するために使用される2つのリンクが含まれています。
動的領域は、タスクフローバインディングを介して「入力パラメータマップ」を受け取ります。
このマップには、テーブルに表示するPOJOと、テーブルの状態とビューにある他の可能なコンポーネントの状態を保持する状態Beanが含まれています(以下の実装を参照)。

問題/要件:

1.事前選択:

テーブルの最初のロード時にPOJOに含まれるデータに従って、テーブル内の1つの行を事前に選択します。

2.タスクフロースイッチを選択し続けます。

テーブル内の選択された行(制限付きタスクフローA)も、別の制限付きタスクフローBに切り替えて、A(テーブルが配置されている場所)に戻った後に選択する必要があります。

3.MDSなし

セーブポイント/MDS機能の使用はありません。

4.一貫性のあるテーブルモデルとバインディングレイヤー

タスクフローを切り替えた後、およびテーブル内の要素を選択した後、選択した行のテーブルコンポーネントとバインディングを要求できるはずです。
テーブルの行とバインディングで選択された行は、タスクフローを切り替えた後、およびテーブル内の要素を選択した後、一貫している必要があります。

すでに試しました:

行を事前に選択し、MDS/セーブポイントを使用せずにタスクフロースイッチを選択し続けます。

いくつかのテーブルプロパティを「状態」Beanにバインドしました。Beanの実装は以下に添付されています。

1.テーブルのプロパティ:

選択された行キー:
selectedRowKeys = "#{pageFlowScope.stateBean.tableStateBean.rowKeySet}"

Backing-RichTableをバインドするBeanプロパティ:
binding = "#{pageFlowScope.stateBean.tableStateBean.richTable}"

デフォルトの選択リスナー
selectionListener="#{bindings.postanschriften.collectionModel.makeCurrent}"

ここで試したこと:
テーブルの初期ロードと行Beanメソッドの変更時にgetRowKeySet(..)が呼び出されます。
このメソッドでは、選択する行は初期テーブルロード時に計算されます(this.rowKeySet == null)。テーブルプロパティselectedRowKeysはBeanのプロパティにバインドされているため、テーブルpageFlowScope.stateBean.tableStateBean.rowKeySetで別の行が選択されると更新されます。タスクフローをAからBに、またはその逆に変更すると、バッキングBeanプロパティrichTableのゲッターが呼び出されます。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のいくつかの値に従って、テーブルの行を事前に選択することはそれほど奇妙ではないと思います。また、制限されたタスクフロー(動的領域)を切り替えた後も、テーブルの選択した行を保持できるはずですよね?

あなたの助けを期待してありがとう

よろしく、

マックス

4

2 に答える 2

0

「選択された」行を設定するのはかなり簡単です。そのための解決策がいくつかあります。これはそのうちの 1 つにすぎません。テーブルをバッキング 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);
于 2012-11-20T11:20:12.613 に答える
0

アプリケーションの設計を確認することをお勧めします。単一のタスク フローを使用して 2 つのビュー アクティビティ (ページ フラグメント) 間を移動する方が、動的領域を使用して 2 つのタスク フローを切り替えるよりも簡単なソリューションになる場合があります。また、行の選択を永続化するためだけに多くのコードを記述しました。選択した行の一意の列のデータを保存し、上記の投稿で DCBinding Iterator を使用して提供されたロジックを使用して、行選択をその行に設定するだけです。

于 2013-03-09T05:42:22.543 に答える