How to save an array in JSF with ui:repeat + h:inputText + managed bean?

孤者浪人 提交于 2020-01-22 08:15:48

问题


In a postgres database I have a table with, among others, an int[] field.

In my model I have a persisted bean that maps the table, including the int[] field. In this class I have implemented all the needed setters/getters.

Now, I have a managed bean which plays also the controller role, and links to the model bean. So, in my xhtml I'm trying to do this:

<ui:repeat value="#{drawsetController.selected.editableBaseSetList}" var="baseNumber">
    <h:inputText value="#{baseNumber}"/>
</ui:repeat>

baseSetList is the int[] array.

The problem is that when I submit my form only this element is not updated. The initialization is working, the getter is called, but not the save, so it must be a bind thing. Long story short, I have tried to replace the int[] array with an ArrayList of a custom class which could wrap the int (like a writable Integer) but it isn't working.

Maybe It's the repeat that doesn't bind properly, I don't really know. This is my first project in java after years and years of PHP :).


回答1:


Don't know if I get you right, but baseNumber is not bound to any property in any managed bean. It only exists in the scope of ui:repeat.

You should do something like:

<ui:repeat value="#{editableBaseSetList}" var="myVariable">
    <h:inputText value="#{managedBean.property}" />
</ui:repeat>



回答2:


If editableBaseSetList is an int[], then baseNumber is an int. You're now binding the input text component to this int.

This binding is however not bidirectional. The input element only gets to see the element you are binding to it, not the collection from which it originates. It thus has no knowledge of how to update this collection.

You thus need to bind to something that can be updated. If your list for instance contained an IntHolder with a getter and setter for the internal integer (say getInt() and setInt()), and the list would be ArrayList you would use:

<ui:repeat value="#{drawsetController.selected.editableBaseSetList}" var="baseNumber">
    <h:inputText value="#{baseNumber.int}"/>
</ui:repeat>

After the postback, JSF will call the setInt() method on each IntHolder in the list with the supplied values.

For a collection that already holds integers or other immutable types, it can be a bit of a hassle to convert it to such collection mentioned above. There is however also another solution. There you don't use the var attribute of ui:repeat but use its index. You then give the h:inputText a binding to the collection indexed by this index var.

E.g.

Suppose you have the following bean:

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

@ManagedBean
@ViewScoped
public class RepeatBean {

    List<Integer> list;

    public List<Integer> getList() {
        return list;
    }

    @PostConstruct
    public void initList() {
        list = new ArrayList<Integer>();
        list.add(10);
        list.add(20);
        list.add(30);
    }

    public String save() {
        // list now contains the values provided by the user.
        return "";

    }

}

Used on the following Facelet:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"        
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    >

    <h:body>

        <h:form>
            <ui:repeat value="#{repeatBean.list}" varStatus="status">            
                <h:inputText value="#{repeatBean.list[status.index]}" />
            </ui:repeat>
            <h:commandButton value="Save" action="#{repeatBean.save}" />
        </h:form>

    </h:body>
</html>

This will initially display 10 20 30 on your screen. When you change the numbers and click save, you can verify via e.g. a break-point that the list instance variable contains the updated numbers.



来源:https://stackoverflow.com/questions/5252708/how-to-save-an-array-in-jsf-with-uirepeat-hinputtext-managed-bean

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!