请读到最后,有很多编辑
我有这段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
语句之后)并再次将所有产品发送到视图中。为什么会发生这种情况?
答案 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");
}
}
更多信息