Please read to the end, there are many EDITS
I have this piece of JSF code:
<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>
The #{productManager.filterProductsByCategory}
commandbutton redirects to this java method:
public void filterProductsByCategory() {
this.products = controller.obtainProductListByCategory(selectedDesiredCategory);
showMessage("Filtered by selected category");
}
Here I update the content of the products
list with the new set of filtered-by-category products to display them in the view. The thing is the page is not reloading to display the new content. How is this achieved?
EDIT: The showMessage method is actually displaying in the view, so the page IS reloading, but for some reason the table is not updating. Maybe it's a problem with the data the query is returning, I'm actually researching.
EDIT: The query is returning good results, as my debugging process confirmed, but the webpage is not reloading the data properly in the table.
EDIT: I found out something really weird. This is the code the JSF page is referencing to:
public void filterProductsByCategory()
{
filtered = true;
products = controller.obtainProductListByCategory(selectedDesiredCategory);
showMessage("Filtered by selected category");
}
I'm now using a boolean value to actually know when I have to deliver a filtered list (See why in the code below) This is the getter
of the products
list:
public List<Product> getProducts()
{
if(filtered)
{
filtered = false;
return products;
}
products = controller.obtainProductList();
return products;
}
Here if it's true it should just send the actual filtered products
variable. But for some reason it's looping again and again inside the method (even after the return
statement inside the if) and sending all the products to the view again. Why is this even happening?
By default, JSF calls the getter methods as much as they're used in the view. For example, for your List<Product> products
field and its respective getter, if #{productManager.products
appears twice in your view ie in the Facelets code, then the getter will be executed twice as well. For this reason, getter and setter methods in managed bean should be as clean as possible and should not contain any business logic involved.
Basically, you should retrieve the product list from database once, after creating the managed bean and before the view render time. To achieve this, you can use @PostConstruct
annotation to decorate a void
method that will be executed after the bean is created.
In code:
@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");
}
}
More info
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.