【问题标题】:Values of h:inputText inside ui:repeat are not processedui:repeat 中的 h:inputText 的值不被处理
【发布时间】:2013-05-14 14:21:51
【问题描述】:

我要处理这个表单(valueChangeListener 在实际情况下是无效的)。

这是后面的豆子:

public class TestBean extends PrivateBaseBean implements Serializable {
private List<String> strings;

@PostConstruct
public void init() {
    strings = new ArrayList<String>();
    strings.add("");
    strings.add("");
    strings.add("");
}

public void saveAction(ActionEvent event) {

    StringBuilder textToShowInMessage = new StringBuilder();
    for (String string : strings) {
        textToShowInMessage.append(string);
        textToShowInMessage.append("; ");
    }
    FacesMessage msg = new FacesMessage(super.getBundle().getString(
            textToShowInMessage.toString()), "");

    FacesContext.getCurrentInstance().addMessage(null, msg);
}

getters... setters...

一个观点:

....
<h:form>
<ui:repeat var="string" value="#{testBean.strings}">
    <h:inputText value="#{string}" />
    <br />
</ui:repeat>
<p:commandButton value="#{msg.save}"
actionListener="#{testBean.saveAction}" icon="ui-icon-disk"
        update="@form" />
</h:form>
...

在后台处理表单时,bean字符串列表始终为空。

如何处理表单输入的内部迭代,没有任何值变化监听器?

有一些截图:

action 或 actionListener on 也会出现同样的问题

【问题讨论】:

  • 你试试:&lt;p:commandButton process="@form" !
  • @RongNK:这已经是默认设置了。将来,请考虑先尝试一下自己。
  • 是的,我总是尝试任何东西,可能是错误,谢谢 BalusC。
  • 这道题的第二级在这里link

标签: jsf primefaces


【解决方案1】:

您的问题与 PrimeFaces &lt;p:commandButton&gt; 的行为无关,而是与使用 &lt;ui:repeat&gt; 标记时隐含创建的范围界定问题有关。

首先,让我们离开您的示例。基本上,你有

<ui:repeat value="#{bean.strings}" var="s">
    <h:inputText value="#{s}"/>
</ui:repeat>

有支持List&lt;String&gt; strings。

罪魁祸首在这里:value="#{s}"。由&lt;ui:repeat&gt; 导出的变量s 仅在其循环内可见,并且它不绑定到任何托管bean 的属性,而仅绑定到局部变量。换句话说,s 并不像人们所期望的那样绑定/等于bean.strings[index],并且正如我们所见,它不知道它的来源。所以基本上,你是单方面的关系:来自 bean 的值被正确地打印在你的输入中,但相反的情况没有发生。

解决方法

解决方法 #1:包装类/模型对象

可以通过为您的类使用包装器对象来克服这种情况。如果是字符串,它可能是“简单可变字符串”,如下所示:

public class MString {
    private String string;//getter+setter+constructor
}

在这种情况下,迭代将按预期进行:

<ui:repeat value="#{bean.mstrings}" var="ms">
    <h:inputText value="#{ms.string}"/>
</ui:repeat>

有支持List&lt;MString&gt; mstrings.

请注意,如果您有您的模型类,例如 User,并且将在 &lt;ui:repeat&gt; 中更改其属性,则该类本身将有效地成为一个包装器,以便适​​当地设置属性。

解决方法 #2:链式属性访问

另一种解决方法是直接从&lt;h:inputText&gt; 标记中访问集合中的元素。这样,任何此类属性都将通过访问 bean,然后是集合,然后在所需索引处设置属性来设置。太长了,但就是这样。至于方法问题,&lt;ui:repeat&gt; 提供了一个导出的当前迭代状态变量varStatus,它将用于访问托管 bean 中的数组/集合。

在这种情况下,迭代也将按预期进行:

<ui:repeat value="#{bean.strings}" var="s" varStatus="status">
    <h:inputText value="#{bean.strings[status.index]}"/>
</ui:repeat>

普通的后盾List&lt;String&gt; strings。

【讨论】:

  • &lt;p:commandButton process&gt; 默认为 @form。更有可能是 bean 管理注释不好或者表单是嵌套的。根据提供的信息,这是不可能回答的,因为 OP 没有发布完整的 SSCCE。
  • @BalusC 这个问题与信息不足的问题无关。它也与嵌套表单/不正确使用的注释无关。分析表明该问题与导出的var 的&lt;ui:repeat&gt; 的作用域有关。因此,我进行了编辑并提出了两种解决方法。至于 PrimeFaces process,我还没有找到默认 @form 的任何文件批准。此外,我发现关于process 的&lt;p:ajax&gt; 文档具有误导性,因为如果我们嵌套两个普通标签,它不会覆盖命令按钮的默认值。不过,简单的测试证实您的发现是正确的。
  • 这基本上在我建议看的另一个问题中得到了回答:)
  • @BalázsMáriaNémeth 哦,是的,完全正确。但是请确保当您绑定基本上充当包装器的模型类时,这不是必需的,更新的答案中确切说明了什么。
  • 这道题的第二级在这里link
【解决方案2】:

我的解决方案直接从页面中获取值:

<ui:repeat id="repeat" value="#{bean.strings}" var="s" varStatus="status">
    <h:inputText id="x" value="#{s.field}"/>
    <h:commandLink style="margin: .5em 0" styleClass="commandLink" actionListener="#{bean.save(status.index)}" value="#{bundle.Send}"/>
</ui:repeat>

保存方法:

public void save(String rowid) {
        String jsParam = Util.getJsParam("repeat:" + rowid + ":x");
        System.out.println("jsParam: " + jsParam); //persist...
    }

getJsParam 方法:

public static String getJsParam(String paramName) {
    javax.faces.context.FacesContext jsf = javax.faces.context.FacesContext.getCurrentInstance();
    Map<String, String> requestParameterMap = jsf.getExternalContext().getRequestParameterMap();
    String paramValue = requestParameterMap.get(paramName);
    if (paramValue != null) {
        paramValue = paramValue.trim();
        if (paramValue.length() == 0) {
            paramValue = null;
        }
    }
    return paramValue;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-17
    • 2015-11-29
    • 1970-01-01
    • 2012-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-12
    相关资源
    最近更新 更多