我无法理解为什么当我在ui中重复时,我的吸气剂没有被调用。重复。我正在使用Glassfish 3.1.1 / Mojarra 2.1.3。
下面的代码将呈现类似
的表格Alice [empty input] [empty output] [link: update value] [link: cancel]
Bob [empty input] [empty output] [link: update value] [link: cancel]
如果我点击Alice行上的“更新值”,然后在“Bob”行上“更新值”,我最终得到:
Alice [Alice] Alice
Bob [Alice] Bob
我不明白为什么“Bob”行的输出正在拾取“Alice”。这就像在渲染响应阶段没有调用getter,而是来自托管bean的旧值在更新模型值阶段停留在UIInput上。
奇怪的是,如果我在Alice行上点击“更新值”,然后“取消”,然后在Bob行上“更新值”,我得到预期结果。
另外,如果我将“@form”添加到“更新值”链接上的render = ...,我将看到正确的值(尽管它们将在每一行上重复)。我不喜欢这个,主要是因为我不想更新整个表来处理单行。
可能导致这种情况的原因是什么?我对JSF生命周期缺少什么?
此外 - 相同的模式在ui之外工作正常:重复。在这种情况下,h:inputText似乎总是使用来自托管bean的正确值刷新,并按照我的预期在“呈现响应”阶段调用getter。
这最初使用的是PrimeFaces p:commandLink,但是我得到了与标准JSF h完全相同的行为:commandLink和f:ajax。
此外,我知道PrimeFaces行编辑器,这可能是一般整体问题的更好解决方案 - 我仍然想知道为什么这不起作用。
谢谢!
相关的XHTML如下
<h:form id="testForm">
<table style="width:400px; ">
<ui:repeat value="#{testBean.customers}" var="customer" varStatus="status">
<tr>
<td><h:outputText id="output" value="#{customer.name}"/></td>
<td><h:inputText id="input" value="#{testBean.customerEdit.name}"/></td>
<td><h:outputText id="otherOutput" value="#{testBean.customerEdit.name}"/></td>
<td>
<h:commandLink actionListener="#{testBean.edit(status.index)}">
<f:ajax execute="@this" render="input otherOutput"/>
Update value
</h:commandLink>
<h:commandLink actionListener="#{testBean.cancel}">
<f:ajax execute="@this" render="input otherOutput"/>
Cancel
</h:commandLink>
</td>
</tr>
</ui:repeat>
</table>
</h:form>
“testBean”托管bean是视图范围的:
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
@ViewScoped
@ManagedBean
public class TestBean implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
public static class Customer {
private String name;
public Customer(String name) {
this.name = name;
}
public String getName() {
System.out.println("returning name: " + name);
return name;
}
public void setName(String name) {
this.name = name;
}
}
private List<Customer> customers;
private Customer customerEdit = new Customer(null);
@PostConstruct
public void init() {
customers = Arrays.asList(new Customer("Alice"),
new Customer("Bob"), new Customer("Carol"), new Customer("David"), new Customer("Eve"));
}
public Customer getCustomerEdit() {
return customerEdit;
}
public void setCustomerEdit(Customer customerEdit) {
this.customerEdit = customerEdit;
}
public void edit(int index) {
System.out.println("Called edit with index: " + index);
customerEdit = new Customer(customers.get(index).getName());
}
public void save(int index) {
System.out.println("Called save with index: " + index + " new name = " + customerEdit.getName());
customers.set(index, customerEdit);
customerEdit = null;
}
public void cancel() {
System.out.println("Called cancel");
customerEdit = null;
}
public List<Customer> getCustomers() {
return customers;
}
public void setCustomers(List<Customer> customers) {
this.customers = customers;
}
}
答案 0 :(得分:0)
你的问题在于这一行:
<h:commandLink actionListener="#{testBean.edit(status.index)}">
你不能以这种方式向actionlisteners发送参数,这不是它的工作原理。您需要将该行更改为:
<h:commandLink actionListener="#{testBean.edit}" customerIndex="#{status.index}>
然后将编辑方法更改为类似的内容。
public void edit(ActionEvent ae) {
int index = ae.getComponent().getAttributes().get("customerIndex");
System.out.println("Called edit with index: " + index);
customerEdit = new Customer(customers.get(index).getName());
}
此外,我不确定您的“保存”方法与其他任何内容的关系,但这可能只是因为您跳过了一些不相关的代码。
编辑:你可以通过这种方式发送参数,如果它是一个javascript方法,但不是托管bean或#{}标签内的任何其他内容。