繁体   English   中英

JSF Datatable的“优雅”方式来编辑行的内容

[英]JSF Datatable “elegant” way to edit the content of a row

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界面中创建这些规则。 我已经有了所需的网站,数据模型等。 但是,一个特殊的问题是,动作规则可以明智地使用一Set of Properties Key-Value 我选择一个TreeMap 现在,我希望能够adddeleteedit代表数据表中的单元格。

Java:createActioNode:

@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}在更改时被调用。 但是,要检索实际记录以及因此要在地图中更改的键和值,我必须遍历DatatableUIComponent ,检索已编辑的记录,保存地图并重建条目集。
所以我的实际问题是 ,这是推荐的方法吗? 我是否监督过一些可以使我的世界变得更加轻松的事情? 有人实施过类似的东西吗?

这是UIData的文档,任何数据表都是其子级:

UIData是一个UIComponent,它支持将数据绑定到由DataModel实例表示的数据对象的集合,这是该组件本身的当前值(通常通过ValueExpression建立)。 在对数据模型中的数据行进行迭代处理期间,当前行的对象作为由var属性指定的键下的request属性公开。

因此,正如您所说的,您需要一个可迭代的对象,以便数据表可以遍历该对象并在构建表时公开每个元素。

另一方面,您在这里没有完全利用绑定功能。 只需让组件完成其工作并设置value=#{ruleTreeBeanAddActionNode.actionParams}actionParamsList或任何其他受支持的类型 完成后,数据表的模型将引用您的ruleTreeBeanAddActionNode.actionParams元素。 您不需要任何其他机制即可进行同步。

也可以看看:

UPDATE

我猜您尝试将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; }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM