2

我有一个带有 ui:repeater 标记的 JSF 页面,它只显示字符串列表和一些用于将字符串添加到列表的控件。添加字符串时,我使用 ajax 更新转发器标记并立即显示新字符串,而无需刷新页面。这是我的页面的样子:

<h:body>
    <h:form>
        <p:inputText id="name" value="#{testController.newString}"/>
        <p:commandButton value="Add" actionListener="#{testController.addString}" update="strings" />
    </h:form>       

    <h:panelGroup id="strings">         
        <ui:repeat var="str" value="#{stringModel.strings}" varStatus="stringData">                                                                                                             
            <div>                                       
                <h:outputText value="#{str}" />
                <h:inputText value="#{str}" />
            </div>                                                                                  
        </ui:repeat>
    </h:panelGroup>                              

</h:body>

除了 inputText 组件外,一切正常。使用 Ajax 更新 ui-repeater 后,仍会显示上一个字符串中的文本。例如,假设最初我有一个包含 2 个字符串“val1”和“val2”的列表。我输入一个名为“val3”的新字符串并提交表单。列表在服务器端正确更新,中继器也更新了,它现在有 3 个元素。但是,虽然新添加的元素中的 h:outputText 将正确显示“val3”,但 inputText 将显示为“val2”作为值。所以我最终得到了这样的东西:

output tag     input tag
val1           val1
val2           val2
val3           val2 (???)

支持 bean 非常简单:一个视图范围的模型 bean

@Component
@Scope("view")
public class StringModel {

    private List<String> strings = Lists.newArrayList("Value 1");

    public List<String> getStrings() {
        return strings;
    }

    public void setStrings(List<String> strings) {
        this.strings = strings;
    }   
}

和一个请求范围的控制器 bean:

@Component
@Scope("request")
public class TestController {

    private String newString;
    @Autowired private StringModel model;

    public void addString() {
        model.getStrings().add(newString);
    }

    public String getNewString() {
        return newString;
    }

    public void setNewString(String newString) {
        this.newString = newString;
    }   

}

我做了一些测试,这实际上对任何输入组件都以相同的方式工作,例如 textInput、textArea 等。任何帮助将不胜感激。

4

3 回答 3

6

我无法详细说明为什么它在更新后显示错误的值(可能是内部循环索引<ui:repeat>被破坏 - 尝试更新的 Mojarra 版本),但只是从varStatus作品中按索引引用字符串项。当您将此列表放入表单时,它还将立即解决将来无法提交已编辑字符串值的问题,因为String该类是不可变的并且没有设置器。

<ui:repeat value="#{stringModel.strings}" var="str" varStatus="loop">
    <div>
        <h:outputText value="#{str}" />
        <h:inputText value="#{stringModel.strings[loop.index]}" />
    </div>
</ui:repeat>
于 2011-08-13T17:19:48.960 回答
2

ui:repeat 中的 EditableValueHolders 在当前版本的 JSF 规范中被破坏(按设计)。它不起作用,没有办法修复它。也许新版本将使 ui:repeat 成为支持保存其子项状态的适当组件。也许不吧。

如果您将 ui:repeat 更改为 h:dataTable,则应该可以正常工作(如果没有,那么您的问题出在其他地方,我错了)。

坦率地说,除了使用其他一些图书馆的中继器之外,没有其他解决方法——你应该在 Tomahawk、特立尼达和许多其他地方找到工作的中继器。Primefaces,AFAIR,没有一个纯粹的中继器。

于 2011-08-13T17:12:14.753 回答
0

我之前也有完全相同的问题。我通过将 inputText 放入表单来解决它。我还复制了您的代码并将其h:inputText放入 a 中h:form,它也可以正常工作。

<h:form>
    <ui:repeat value="#{stringModel.strings}" var="str" varStatus="loop">
        <div>
            <h:outputText value="#{str}" />
            <h:inputText value="#{str}" />
        </div>
    </ui:repeat>
</h:form>
于 2013-02-03T09:31:59.100 回答