JSF <h:inputtext> / <h:outputtext>不根据布尔值进行渲染</h:outputtext> </h:inputtext>

时间:2014-01-03 16:30:26

标签: java jsf java-ee jsf-2

我有一个<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;
}

1 个答案:

答案 0 :(得分:2)

在测试您的示例之后,唯一可能的错误是您正在使用RequestScoped bean。为了使其有效,您至少需要ViewScopedSessionScoped。另外,每次请求(按钮操作)都会丢失productList更改的内容。

根据编辑,第二个错误是如何获取数据。您需要将数据加载到除此之外的其他地方:

@PostConstruct
public void init()
{
    productList = gnomeFacade.findAll();
}

public List<Gnome> getProductList()
{
    return productList;
}

另外,每次操作都会重置列表。