JSF页面没有在表单操作上重新加载

时间:2013-10-16 21:49:42

标签: java jsf

请读到最后,有很多编辑
我有这段JSF代码:

<h:form>
    <h:dataTable class="table-striped" var="_product"
        value="#{productManager.products}"
        border="1"
        binding="#{productManager.table}">
        <h:column>
            <f:facet name="header">Product</f:facet>
            #{_product.name}
        </h:column>
        <h:column>
            <f:facet name="header">Available Units</f:facet>
            #{_product.stock}
        </h:column>
        <h:column>
            <f:facet name="header">Category</f:facet>
            #{_product.category}
        </h:column>
        <h:column>
            <f:facet name="header">Price</f:facet>
            #{_product.price}
        </h:column>
        <h:column>
            <f:facet name="header">Description</f:facet>
            #{_product.description}
        </h:column>
        <h:column>
            <f:facet name="header">Select</f:facet>
            <h:commandButton class="btn btn-primary" value="Select"
                action="#{productManager.selectProduct}"/>
        </h:column>
    </h:dataTable>
</h:form>
<h:form>
    <h:outputLabel for="productName">Selected Product: </h:outputLabel>
    <h:inputText value="#{productManager.selectedDesiredCategory}"/>
    <h:commandButton value="Filter category" action="#{productManager.filterProductsByCategory}"/>
    <h:outputText id="productName" value="#{productManager.selectedName}"/><br/>
    <h:outputLabel for="units">Units: </h:outputLabel>
    <h:inputText id="units" value="#{productManager.selectedUnits}"/>
    <h:commandButton value="Add to basket" action="#{productManager.addToBasket(accountManager.username)}"/><br/>
    <h:outputText rendered="#{productManager.availableMessages}"
        value="#{productManager.message}"/>
</h:form>

#{productManager.filterProductsByCategory}命令按钮重定向到此java方法:

public void filterProductsByCategory() {
    this.products = controller.obtainProductListByCategory(selectedDesiredCategory);
    showMessage("Filtered by selected category");
} 

在这里,我使用新的按类别筛选的产品集更新products列表的内容,以在视图中显示它们。事情是页面没有重新加载以显示新内容。这是如何实现的?

编辑:showMessage方法实际上是在视图中显示,因此页面重新加载,但由于某种原因,表格没有更新。也许这是查询返回的数据的问题,我实际上正在研究。

编辑:当我的调试过程确认时,查询返回了良好的结果,但网页没有在表格中正确地重新加载数据。

编辑:我发现了一些非常奇怪的东西。这是JSF页面引用的代码:

public void filterProductsByCategory()
   {
      filtered = true;
      products = controller.obtainProductListByCategory(selectedDesiredCategory);
      showMessage("Filtered by selected category");
   } 

我现在使用布尔值实际知道何时必须提供过滤列表(请参阅下面的代码中的原因)这是getter列表的products:< / p>

   public List<Product> getProducts()
   {
      if(filtered)
      {
          filtered = false;
          return products;
      }
      products = controller.obtainProductList();
      return products;
   }

如果这是真的,它应该只发送实际过滤的products变量。但由于某种原因,它在方法内一次又一次地循环(即使在if中的return语句之后)并再次将所有产品发送到视图中。为什么会发生这种情况?

1 个答案:

答案 0 :(得分:3)

默认情况下,JSF调用getter方法,就像在视图中使用它们一样。例如,对于您的List<Product> products字段及其相应的getter,如果#{productManager.products在您的视图中显示两次,即在Facelets代码中,则getter将执行两次也是。因此,托管bean中的getter和setter方法应尽可能干净,不应包含任何涉及的业务逻辑。

基本上,在创建托管bean之后和视图渲染时间之前,您应该从数据库中检索一次产品列表。为此,您可以使用@PostConstruct注释来修饰将在创建bean之后执行的void方法。

在代码中:

@ManagedBean
@ViewScoped
public class ProductManager {
    private List<Product> products;
    @PostConstruct
    public void init() { //you can change the method name
        //if you manually handle the controller, initialize it here
        //otherwise, let it be injected by EJB, Spring, CDI
        //or whichever framework you're working with
        products = controller.obtainProductList();
    }
    public List<Product> getProducts() {
        //plain getter, as simple as this
        //no business logic AT ALL
        return this.products;
    }
    public void filterProductsByCategory() {
        filtered = true;
        products = controller.obtainProductListByCategory(selectedDesiredCategory);
        //I guess this method logs a message or something...
        showMessage("Filtered by selected category");
    }
}

更多信息