我有一个带有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之后,它仍然显示来自前一个字符串的文本。例如,假设最初我有一个包含两个字符串的列表,"val1"one_answers"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等。如有任何帮助,不胜感激。
我不能详细说明为什么它在更新后显示错误的值(这将是<ui:repeat>
的内部循环索引被打破—尝试一个新的Mojarra版本),但只是引用字符串项目从varStatus
的索引工作。它也将立即修复未来无法提交编辑字符串值的问题,当你把这个列表在一个形式,因为String
类是不可变的,没有setter。
<ui:repeat value="#{stringModel.strings}" var="str" varStatus="loop">
<div>
<h:outputText value="#{str}" />
<h:inputText value="#{stringModel.strings[loop.index]}" />
</div>
</ui:repeat>
ui:repeat中的editablevalueholder在当前版本的JSF规范中被破坏了(由于设计)。它行不通,没有办法修理它。也许新版本会让ui:重复一个合适的组件,支持保存其子组件的状态。也许不是。
如果你改变ui:repeat为h:dataTable,事情应该工作(如果不是,那么你的问题是在其他地方,我错了)。
坦率地说,除了使用其他图书馆的中继器之外,没有其他解决办法-你应该在Tomahawk, Trinidad和许多其他地方找到工作中继器。Primefaces, AFAIR,没有纯中继器
我以前也遇到过完全相同的问题。我通过把inputText放到一个表单中解决了这个问题。我还复制了您的代码,并将h:inputText
放入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>