2012-09-16 39 views
0

我想在用戶單擊具有該產品名稱的鏈接時顯示有關產品的詳細信息。h:commandLink在ui中不起作用:重複

在調試我的代碼時,我發現以下代碼中顯示的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"; 
} 
+1

第二CommandLink不指向的方法,但只到Bean。這是一個錯字還是你的實際代碼? –

回答

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

} 
+0

@Arijan:我正在使用JSF 2.1。我也嘗試把ui放在窗體的內部,但它不運行。 ProductBean是SessionScoped,它也有一個方法(顯示列表產品類別名稱) - user1542080 10分鐘前 – hoanvd1210

+0

因此,對於JSF 2.1,至少你沒有使用隱藏字段,並可以直接交出當前迭代的項目該方法。對於這個用例,SessionScoped是** WRONG **(想想如果人們打開多個選項卡會發生什麼),但至少它應該保留現在的數據。我認爲你需要展示你的整個支持bean。具體來說,初始化ui:repeat數據的部分很重要。此外,'ui:repeat'是否有任何具有'rendered'屬性的父標記? –

+0

listProducts顯示在頁面中。我認爲它在''有問題。我嘗試使用不在''內的commandLink。在這種情況下,這是事實。 – hoanvd1210

0

通過查看上面的代碼

你打開<ui:repeat>標籤,但沒有關閉它,並試圖把整個<ui:repeat>形式內,檢查你的網頁是一個<h:form>標籤內h:form。如果它沒有工作,那麼檢查你的bean是否在視圖範圍內,如果沒有放在視圖範圍內。

+0

未封閉的''只是一個代碼格式錯誤。 OP沒有仔細注意代碼格式化規則和消息預覽(就像你最初一樣)。 – BalusC

+0

不,我沒有收到編譯器的錯誤,所有的標籤都關閉了。 – hoanvd1210

+0

@ user1542080將您的支持bean類放在視圖範圍內,並檢查它是否正常工作 – divine