我有一个<h:dataTable>
从实体类填充并显示不同的产品。我希望能够单击<h:commandLink>
并编辑该链接所属的行。我的结构大致与mkyong上这个很好的例子和文章相同。
该表(排除了一些列):
<h:form>
<h:dataTable id="gnomeTable" value="#{gnome.productList}"
var="item"
styleClass="gnomeTable"
headerClass="gnomeTableHeader"
rowClasses="gnomeTableOddRow,gnomeTableEvenRow"
bgcolor="#F1F1F1" border="10" cellspacing="2"
rules="all" >
<f:facet name="header">
<h:outputText value="List of available gnomes for sale" />
</f:facet>
<h:column>
<f:facet name="header">
<h:outputText value="GnomeID" />
</f:facet>
<h:outputText value="#{item.id}"></h:outputText>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Name"/>
</f:facet>
<h:outputText value="#{item.name}" rendered="#{not item.editable}"></h:outputText>
<h:inputText value="#{item.name}" rendered="#{item.editable}"></h:inputText>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Available"/>
</f:facet>
<h:outputText value="#{item.available}" rendered="#{not item.editable}"></h:outputText>
<h:inputText value="#{item.available}" rendered="#{item.editable}"></h:inputText>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Edit"/>
</f:facet>
<h:commandLink value="Edit" action="#{gnome.editAction(item)}" rendered="#{not item.editable}" />
</h:column>
</h:dataTable>
<h:commandButton value="Save Changes" action="#{gnome.saveAction}" />
</h:form>
Bean方法:
public String saveAction() {
for (Gnome g : productList) {
g.setEditable(false);
}
return null;
}
public String editAction(Gnome gnome) {
gnome.setEditable(true);
return null;
}
实体类中的属性boolean editable
注释为@Transient,因为它不是持久数据的一部分,我不希望实体管理器触及它:
@Transient
private boolean editable;
我认为这会导致boolean
变量在单击“编辑”按钮时设置为true,该行将重新呈现,字段现在为<h:inputText>
,但没有任何反应。我调试了它并确保变量设置为true,它就是。
我还发现这个SO question我认为可能与我遇到的问题类似。但不同之处在于刷新页面不会改变任何内容。
我错过了什么?
编辑1: 在这个问题的第一个版本中,我错误地粘贴了错误的代码。现在包含的是我当前的代码,理论上应该有效,但不是。
编辑2:
productList
的初始化,其中Gnome
是实体类。
private List<Gnome> productList = new ArrayList<>();
public List<Gnome> getProductList() {
productList = gnomeFacade.findAll();
return productList;
}
public void setProductList(List<Gnome> productList) {
this.productList = productList;
}
答案 0 :(得分:2)
在测试您的示例之后,唯一可能的错误是您正在使用RequestScoped
bean。为了使其有效,您至少需要ViewScoped
或SessionScoped
。另外,每次请求(按钮操作)都会丢失productList
更改的内容。
根据编辑,第二个错误是如何获取数据。您需要将数据加载到除此之外的其他地方:
@PostConstruct
public void init()
{
productList = gnomeFacade.findAll();
}
public List<Gnome> getProductList()
{
return productList;
}
另外,每次操作都会重置列表。