1

EDIT1:Valentin Jacqueminが示唆したように、私はそれを実装しましたList<Entry<String,String>> が、値を変更すると、Tomcatはエラーをスローします:エラーメッセージ:

    SEVERE: /bvDesktop_RuleOverviewAddActionNode.xhtml at line 111 and column 115 value="#{paramListKVs.value}": Property 'value' not writable on type java.lang.Object
javax.el.PropertyNotFoundException: /bvDesktop_RuleOverviewAddActionNode.xhtml at line 111 and column 115 value="#{paramListKVs.value}": Property 'value' not writable on type java.lang.Object

そして、私のxhtmlの対応する行:

<p:dataTable id="paramListKV" var="paramListKVs" value="#{ruleTreeBeanAddActionNode.paramListKV}" editable="true" editMode="cell">
    <p:column>
        <f:facet name="header">List Key</f:facet>
            <h:outputText value="#{paramListKVs.key}"/>
    </p:column>
    <p:column>
        <p:cellEditor id="paramListKVsEditTest"> 
             <f:facet name="header">List Value</f:facet>
             <f:facet name="output"><h:outputText value="#{paramListKVs.value}"/></f:facet>
             --><f:facet name="input"><p:inputText value="#{paramListKVs.value}" style="width:96%" /></f:facet><--
        </p:cellEditor>
    </p:column>
</p:dataTable>

--> と <-- でマークされています。Javaがコードを書き込もうとしている対象がわかりません。正しいかどうかさえわかりませんvalue="#{paramListKVs.value}"。何か案は?


解決できた特定の問題がありますが、私の解決策は汚い方法のように感じます。これを行うためのよりエレガントな方法があることを願っていますが、見つけることができませんでした(そう検索しました)。だからここに私の問題があります:

私は現在、いくつかのファイルの自動処理のためのルールベースのフレームワークを作成しており、編集者がそれらのルールを素敵で簡単な Web インターフェイスで作成できるようにしたいと考えています。必要な Web サイト、データモデルなどは既にあります。ただし、特定の問題の 1 つは、Action-Rule が wi​​se を持つことができることSet of Properties Key-Valueです。を選択しますTreeMap。今、私はできるようにしたいadddeleteそしてedit表すデータテーブルのセル。

Java: createActionNode:

@ManagedBean
public class RuleTreeBeanAddActionNode {
...
        private TreeMap<String,String> actionParamMap = new TreeMap<String,String>(); 

        private String paramKeyToAdd = "";

        private String paramValueToAdd = "";

        private int paramKeyIndex;

        private String valueToChange;

        private String keyForInfo;

        private UIComponent datatable;

        public void addKeyValueToMap() {

            if((paramKeyToAdd != null || !paramKeyToAdd.equals("")) && (paramValueToAdd != null) || !paramValueToAdd.equals("")) {
            unusedActionParamKeys.remove(paramKeyToAdd);
            usedActionParamKeys.add(paramKeyToAdd);

            actionParamsAsListKeys.add(paramKeyToAdd);
            actionParamsAsListValues.add(paramValueToAdd);

            actionParamMap.put(paramKeyToAdd, paramValueToAdd);
            actionParamMapEntries = new ArrayList<Entry<Integer, String>>((Collection<? extends Entry<Integer, String>>) actionParamMap.entrySet());
            userSession.setAttribute("actionParamMap", actionParamMap);
            userSession.setAttribute("unusedActionParamKeys", unusedActionParamKeys);
            userSession.setAttribute("usedActionParamKeys", usedActionParamKeys);
            userSession.setAttribute("tempSelectorWorkOn", "");
            userSession.setAttribute("tempRuleId", "");

            userSession.setAttribute("actionParamsAsListKeys", actionParamsAsListKeys);
            userSession.setAttribute("actionParamsAsListValues", actionParamsAsListValues);

            paramKeyToAdd = "";
            paramValueToAdd = "";
           }
        }

        public void setValueToChange(String valueToChange) {
            DataTable dt = (DataTable)datatable;
            String id = String.valueOf(paramKeyIndex);
            Entry<String, String> temp = (Entry<String, String>)dt.getRowData();
            actionParamMap.put((String) temp.getKey(), valueToChange);
    }

        //getter and setter

createActionNode.xhtml

<tr>
    <td>Action Parameter </td>
    <td>
        <p:dataTable binding="#{ruleTreeBeanAddActionNode.datatable}" 
                     rowKey="test" 
                     rowIndexVar="paramKeyIndex" 
                     id="paramKeysValues" 
                     var="params" 
                     value="#{ruleTreeBeanAddActionNode.actionParamMapEntries}" 
                     editable="true" 
                     editMode="cell">
            <p:column id="keys">
                <f:facet name="header">Param Key</f:facet>
                <h:outputText value="#{params.key}"/>
            </p:column>
            <p:column id="values">
                <f:facet name="header">Param Value</f:facet>
                <p:cellEditor id="paramValueEdit">  
                   <f:facet name="output"><h:outputText value="#{params.value}"/></f:facet>  
                   <f:facet name="input"><p:inputText id="evinput" value="#{ruleTreeBeanAddActionNode.valueToChange}" style="width:96%"/></f:facet>  
                </p:cellEditor>  
            </p:column>
        </p:dataTable>
    </td>
</tr>
<tr><td><br/></td></tr>
<tr>
    <td>Param To Value</td>
    <td>
        <table>
            <tr>
                <td>
                    <p:selectOneMenu id="paramKeys" value="#{ruleTreeBeanAddActionNode.paramKeyToAdd}">
                        <f:selectItems value="#{ruleTreeBeanAddActionNode.unusedActionParamKeys}"/>
                    </p:selectOneMenu>
                </td>
                <td>
                    <p:inputText id="paramValue" value="#{ruleTreeBeanAddActionNode.paramValueToAdd}"/>
                </td>
            </tr>
            <tr>
                <td></td>
                <td>
                    <p:commandButton id="addParam" value="+" action="#{ruleTreeBeanAddActionNode.addKeyValueToMap}" update="paramKeysValues,paramKeys,paramValue"/>
                </td>
            </tr>
        </table>
    </td>
</tr>    

データテーブルがそれを反復できるように、マップではなくエントリセットを返す必要があることを理解しました。したがって、セル内のレコードを編集すると、変更時に関数
#{ruleTreeBeanAddActionNode.valueToChange}が呼び出されます。ただし、実際のレコードを取得し、マップで変更するキーと値を取得するには、 UIComponentofDatatableを調べて、編集したレコードを取得し、マップを保存して、エントリ セットを再構築する必要があります。
だから私の実際の質問は、これは推奨される方法ですか? 私の世界をより簡単にする何かを監督しましたか? 他の誰かがこのようなものを実装しましたか?

4

1 に答える 1

1

データテーブルの子であるUIDataのドキュメントは次のとおりです。

UIData は、DataModel インスタンスによって表されるデータ オブジェクトのコレクションへのデータ バインディングをサポートする UIComponent です。これは、このコンポーネント自体の現在の値です (通常は ValueExpression によって確立されます)。データ モデル内のデータ行に対する反復処理中に、現在の行のオブジェクトが、var プロパティで指定されたキーの下の要求属性として公開されます。

したがって、あなたが言ったように、テーブルを作成するときにデータテーブルがループして各要素を公開できるように、反復可能なオブジェクトが必要です。

一方、ここではバインド機能を完全に活用していません。コンポーネントにジョブを実行させて、value=#{ruleTreeBeanAddActionNode.actionParams}またはその他のサポートされている型に設定します。完了すると、データテーブルのモデルが要素を参照します。同期を行うための追加のメカニズムは必要ありません。actionParamsListruleTreeBeanAddActionNode.actionParams

以下も参照してください。

アップデート

リストのエントリとしてAbstractMap.SimpleEntryを使用しようとしたと思います。このクラスは JavaBean 互換でsetValueはありませんが、 は 型ではありませんvoid。行の状態を保持する独自のオブジェクトを作成して、JavaBean と互換性のあるオブジェクトを作成し、EL が読み取り/書き込みメソッドを正しく解決できるようにします。

public class Entry{
    private String key;
    private String value;

    public Entry(String key, String value) {
        this.key = key;
        this.value = value;
    }

    public String getKey() {return key;}
    public String getValue() {return value;}
    public void setKey(String key) {this.key = key;}
    public void setValue(String value) {this.value = value;}
}

次に、バッキング Bean で次のようにします。

@ManagedBean
public class RuleTreeBeanAddActionNode {
    private List<Entry> entries;

    @PostConstruct
    public void init() {
        entries = new ArrayList<Entry>();
        entries.add(new Entry("foo", "bar"));
    }

    public List<Entry> getEntries() { return entries; }
}
于 2013-10-22T08:06:22.590 に答える