当用户点击包含该产品名称的链接时,我想显示有关产品的详细信息。
调试我的代码时,我发现下面代码中显示的details
方法没有运行。
我的代码:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:body>
<ui:composition template="/Shared/layout.xhtml" >
<ui:define name="title">Product</ui:define>
<ui:define name="body">
<div id="contents" >
<h3> List Product in Site </h3>
<ul>
<ui:repeat value="#{productBean.listProduct}" var="p">
<div id="list-item">
<div class='item' >
<div class='item-img' >
<h:form>
<input type="hidden" name="productId" value="#{p.productId}" />
<h:commandLink action="#{productBean.details}">
<h:graphicImage url="#{p.picture}" alt='No Picture' />
</h:commandLink>
</h:form>
</div>
<h:form>
<input type="hidden" name="productId" value="#{p.productId}" />
<h:commandLink value="#{p.name}" action="#{productBean}" >
</h:commandLink>
</h:form>
</div>
</div>
</ui:repeat>
</ul>
<h:form>
<h:commandLink value="text" action="#{productBean.test}"> <!-- test -->
</h:commandLink>
</h:form>
</div>
</ui:define>
</ui:composition>
</h:body>
的ProductBean:
@ManagedBean
@RequestScoped
public class ProductBean implements Serializable {
private List<Products> listProduct;
private List<Categories> listCategory;
private Products product;
public Products getProduct() {
return product;
}
public void setProduct(Products product) {
this.product = product;
}
public ProductBean() {
listCategory = new ProductsDB().listCategory();
}
private int categoryId;
public int getCategoryId() {
return categoryId;
}
public void setCategoryId(int categoryId) {
this.categoryId = categoryId;
}
public String listProductByCt() {
try {
String value = FacesContext.getCurrentInstance().
getExternalContext().getRequestParameterMap().get("categoryId");
setCategoryId(Integer.parseInt(value));
if (categoryId == 0) {
return "index";
}
listProduct = new ProductsDB().listProducts(categoryId);
return "product";
} catch (Exception e) {
return "error";
}
}
public String details() {
String s = "";
try {
String productId = FacesContext.getCurrentInstance().
getExternalContext().getRequestParameterMap().get("productId");
if (productId != null) {
product = new ProductsDB().getProductById(productId);
return "details";
}
} catch (Exception e) {
return "error";
}
return "error";
}
public String test()
{
return "s";
}
public List<Categories> getListCategory() {
return listCategory;
}
public void setListCategory(List<Categories> listCategory) {
this.listCategory = listCategory;
}
public List<Products> getListProduct() {
return listProduct;
}
public void setListProduct(List<Products> listProduct) {
this.listProduct = listProduct;
}
}
我还尝试了另一种名为test
的方法。这也是products.xhtml
上的操作引用的,但该操作未放在<ui:repeat>
内。在这种情况下,该方法确实会被执行。
测试方法:
public String test() {
String productId = "IP16G";
product = new ProductsDB().getProductById(productId);
return "details";
}
答案 0 :(得分:4)
您使用的是哪个版本的JSF?
您在ui:repeat
中使用不同形式和隐藏输入显示的代码并不是真正惯用的JSF。您的第一个命令链接的操作中也存在拼写错误。它说produtBean
,但我想它应该是productBean
。如果你点击那个命令链接,JSF会给你一个例外。
你有这个例外,或者什么也没发生?
如果没有发生任何事情,可能的原因是用于呈现命令链接(#{productBean.listProduct}
)的数据在回发后不再可用。您使用什么方法来获取此数据以及Bean的范围是什么?在许多情况下,您应该使用@ViewScoped
并在请求不回发时初始化数据。
此外,请确保默认情况下没有<ui:repeat>
的父组件具有设置为false
的呈现属性。如果此属性在生命周期的某个时刻将设置为true
,则可能在此之后 - 处理链接上的点击。如果发生这种情况,在处理点击时它仍然是false
,这会导致它被无声地忽略。
您可以将测试命令链接放在<ui:repeat>
:
<ui:repeat value="#{productBean.products}" var="product">
...
</ui:repeat>
<h:commandLink value="test" action="#{productBean.test}" />
虽然您使用多个表单和隐藏字段的方法确实有效,但更惯用的JSF版本将是:
<h:form>
<ui:repeat value="#{productBean.products}" var="product">
<h:commandLink action="#{productBean.details(product)}">
<h:graphicImage url="#{product.picture}" alt="No Picture" />
</h:commandLink>
<h:commandLink value="#{product.name}" action="#{productBean.details(product)}" />
</ui:repeat>
</h:form>
使用bean的details
方法:
public String details(Product product) {
this.product = product;
return "details";
}
(获取更多偏离主题的内容,但如果您的所有方法都返回导航案例,则可能需要考虑使用<h:link>
等直接链接,并将产品的ID作为参数。这将使用GET转到目标页面,在这种情况下更清洁)
修改强>
为了测试问题是否不在其他地方,请尝试以下代码。它是一个页面和一个支持bean。将这些添加到您的项目并请求页面。这应该有用。
forminloop.xhtml:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:body>
<ui:repeat value="#{formInLoopBacking.items}" var="item">
<h:form>
<h:commandLink value="#{item}" action="#{formInLoopBacking.action}"/>
</h:form>
</ui:repeat>
</h:body>
</html>
FormInLoopBacking.java
import javax.faces.bean.ManagedBean;
@ManagedBean
public class FormInLoopBacking {
private String[] items = {"A", "B"};
public String[] getItems() {
return items;
}
public void action() {
System.out.println("Action called");
}
}
答案 1 :(得分:0)
查看上面的代码
您已打开<ui:repeat>
标记,但未将其关闭,并尝试将整个<ui:repeat>
放入表单中,并在<h:form>
内检查您的网页是h:form
标记。如果它不起作用,那么检查你的bean是否在视图范围内,如果没有放入视图范围。