【问题标题】:JSF page not reloading on form actionJSF 页面未在表单操作时重新加载
【发布时间】:2013-10-25 05:24:14
【问题描述】:

请阅读到最后,有很多EDITS
我有这段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");
   } 

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

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

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

【问题讨论】:

  • 看起来您的 products 的 getter 不是普通的 getter,即可能包含自己的业务逻辑。
  • @LuiggiMendoza 我在我的代码中发现了一些非常奇怪的东西。我将编辑问题,以便您查看。请继续关注。

标签: java jsf


【解决方案1】:

默认情况下,JSF 调用 getter 方法的次数与在视图中使用的次数一样多。例如,对于您的List&lt;Product&gt; products 字段及其各自的getter,如果#{productManager.products 在您的视图中出现两次,即在Facelets 代码中,那么getter 将被执行两次也是。出于这个原因,托管 bean 中的 getter 和 setter 方法应尽可能干净,并且不应包含任何涉及的业务逻辑。

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

在代码中:

@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");
    }
}

更多信息

【讨论】:

  • 效果惊人。我希望我能更好地理解这一点,但我会继续阅读。感谢您的帮助!
猜你喜欢
  • 2013-11-19
  • 2018-05-21
  • 1970-01-01
  • 2016-06-26
  • 2017-01-22
  • 1970-01-01
  • 2019-01-20
相关资源
最近更新 更多