写入h:dataTable中h:inputText中的map属性

Mr_*_*s_D 4 jsf jsf-2.2

我想添加一个输入文本,用户可以在其中编辑数量 h:dataTable

<h:dataTable id="checkout_table" value="#{cartController.cart.entrySet()}"
    var="item" >
    <h:column>
        <f:facet name="header">Movie</f:facet>
        #{item.key.title} - #{item.key.getAvailable()}
    </h:column>
    <h:column>
        <f:facet name="header">Quantity</f:facet>
        <h:inputText id="quantity"
            value="#{item.value}" redisplay="true"
            converterMessage="Please provide an integer" required="true"
            requiredMessage="Please enter a quantity">
            <!-- <f:validateLongRange minimum="1"
                maximum="#{item.key.getAvailable()}" />
                    this validation must be performed on set-->
            <f:ajax event="blur" render="quantityMessage" />
        </h:inputText>
    </h:column>
    <h:column><h:commandButton value="edit"
        action="#{cartController.addMovieToCart(item.key, item.value)}" />
    </h:column>
    <h:column><h:commandButton value="delete"
        action="#{cartController.removeMovie(item.key)}" />
    </h:column>
    <h:column><h:message id="quantityMessage" for="quantity" /></h:column>
</h:dataTable>
Run Code Online (Sandbox Code Playgroud)

因为它现在抛出了异常The class 'java.util.LinkedHashMap$Entry' does not have a writable property 'value'.我已经阅读了有关绑定的各种内容,但无法完全理解它们.如何为此输入字段定义getter和setter?我可以使用其他一些组件吗?

如果验证也可以处理,那将是值得赞赏的!

编辑:在@BalusC回答后,我设法读取并写入地图 - 有一点需要注意 - 我java.lang.String cannot be cast to java.lang.Integer在bean中得到一个CCE

private Map<Movie, Integer> cart = new LinkedHashMap<>();

public String addMovieToCart(Movie movie, Integer quantity) {
    if (quantity > movie.getAvailable()) {
        String message = "Available copies are " + movie.getAvailable();
        FacesContext.getCurrentInstance().addMessage(null,
            new FacesMessage(FacesMessage.SEVERITY_ERROR, message, null));
        return null;
    }
    Integer ordered = cart.get(movie); // CCE here !
    // etc
}
Run Code Online (Sandbox Code Playgroud)

这最终解决了:

<h:inputText id="quantity"
    value="#{cartController.cart[item.key]}"
    converterMessage="Please provide an integer" required="true"
    requiredMessage="Please enter a quantity" converter="javax.faces.Integer">
Run Code Online (Sandbox Code Playgroud)

请注意转换器 - 显然JSF将地图元素转换为String?一个必须显式转换为整数

没有omnifaces的验证看起来很难(由于渲染/查看时间)

Bal*_*usC 11

如果要Map在EL中具有可写值,则需要括号表示法,
#{map[entry.key]}其中将键作为另一个变量传递.该#{entry.value}确实不会,因为这是只读的,由异常指示工作.

所以,这应该在你的特定情况下做:

<h:dataTable value="#{cartController.cart.entrySet()}" var="item">
    ...
    <h:inputText ... value="#{cartController.cart[item.key]}" />
Run Code Online (Sandbox Code Playgroud)

至于valiator,这个答案适用:在ui:repeat中使用带有变量属性的验证器

顺便说一下,该redisplay属性不受支持<h:inputText>.也许你很困惑<h:inputSecret>