2008-11-18 32 views
20

Trong một JSF DataTable tôi muốn hiển thị các chỉ số hàng bên cạnh các hàng ... như:Làm thế nào để hiển thị các chỉ số hàng trong một JSF DataTable

Column A Column B 
1   xxx 
2   yyy 

Tôi nghĩ rằng tôi có thể sử dụng một biến el ngầm như # {rowIndex} nhưng điều này không hoạt động.

Một giải pháp tôi thấy là để tạo ra một ràng buộc cho bảng dữ liệu và sử dụng các ràng buộc như:

<h:dataTable var="item" value="#{controller.items}" binding="#{controller.dataTable}"> 
    <h:column>#{controller.dataTable.rowIndex}</h:column> 
    <h:column>value</h:column> 
</h:dataTable> 

nhưng giải pháp này rất phức tạp và không làm việc tốt khi tôi có nhiều DataTables lồng nhau trong một trang .

Bất kỳ ý tưởng nào về cách giải quyết vấn đề này theo cách tốt hơn?

+0

Xem [http: // stackoverflow.com/questions/14633008/jsf-2-datatable-row-index-không-datamodel]. Câu trả lời này mới hơn những câu hỏi dưới đây - cũng ngắn và ngọt ngào. – fr13d

Trả lời

15

Giải pháp hiện tại không tấn công tôi như một giải pháp tồi. RowIndex nên làm việc trong các bảng lồng nhau, miễn là bạn đang tham chiếu đến mô hình của bảng lồng nhau. mô hình

<h:dataTable border="1" value="#{nestedDataModel}" var="nested"> 
     <h:column> 
      <h:dataTable border="1" value="#{nested}" var="item"> 
       <h:column> 
        <h:outputText value="#{nested.rowIndex}" /> 
       </h:column> 
       <h:column> 
        <h:outputText value="#{item}" /> 
       </h:column> 
      </h:dataTable> 
     </h:column> 
    </h:dataTable> 

mẫu:

public class NestedDataModel extends DataModel implements Serializable { 

    private List<List<String>> nestedDataModel = populateModel(); 
    private int index; 

    private List<List<String>> populateModel() { 
     List<List<String>> list = new ArrayList<List<String>>(); 
     for(int x=0; x<3; x++) { 
      List<String> nestedTableData = new ArrayList<String>(); 
      for(int y=0; y<3; y++) { 
       nestedTableData.add("Foo x="+x+" y="+y); 
      } 
      list.add(nestedTableData); 
     } 
     return list; 
    } 

    @Override 
    public int getRowCount() { 
     return nestedDataModel.size(); 
    } 

    @Override 
    public Object getRowData() { 
     List<String> list = nestedDataModel.get(index); 
     return new ListDataModel(list); 
    } 

    @Override 
    public int getRowIndex() { 
     return index; 
    } 

    @Override 
    public Object getWrappedData() { 
     return nestedDataModel; 
    } 

    @Override 
    public boolean isRowAvailable() { 
     return index >= 0 && index < nestedDataModel.size(); 
    } 

    @Override 
    public void setRowIndex(int arg0) { 
     index = arg0; 
    } 

    @Override 
    public void setWrappedData(Object arg0) { 
     throw new UnsupportedOperationException(); 
    } 

} 

DataTables làm tổ thường nên tránh - nếu bạn không cẩn thận (ví dụ như làm cho họ con của một hình thức), điều này có thể dẫn đến một O (N^2) vượt qua các bảng trẻ em cho mỗi giai đoạn của vòng đời trên một trình (và có 6 giai đoạn trong vòng đời).


Đối với một cái gì đó bên ngoài để các mô hình, bạn có thể sử dụng một bộ đếm đơn giản trong một bean được quản lý:

public class RowCounter implements Serializable { 

    private transient int row = 0; 

    public int getRow() { 
     return ++row; 
    } 

} 

Config:

<managed-bean> 
    <managed-bean-name>rowCounter</managed-bean-name> 
    <managed-bean-class>tablerows.RowCounter</managed-bean-class> 
    <managed-bean-scope>request</managed-bean-scope> 
</managed-bean> 

Xem:

<f:view> 
    <h:dataTable border="1" value="#{tableDataBean.tableDataModel}" 
     var="rowBean"> 
     <h:column> 
      <h:outputText value="#{rowCounter.row}" /> 
     </h:column> 
     <h:column> 
      <h:outputText value="#{rowBean}" /> 
     </h:column> 
    </h:dataTable> 
</f:view> 

Điều này hoạt động vì hạt đậu s phạm vi yêu cầu và ràng buộc với một điều khiển chỉ đọc bên ngoài một biểu mẫu. Nó sẽ không làm việc trong một dataTable lồng nhau trừ khi bạn muốn các hàng truy cập được toàn cầu để xem. Nhưng sau đó, tôi không tin rằng chỉ số hàng phải là một chức năng của khung nhìn.

Đối với bảng dữ liệu lồng nhau, bạn nên tắt chỉ mục hàng từ bean hàng. Nó cung cấp cho bạn nhiều quyền kiểm soát hơn nếu bạn quyết định thực hiện những việc như phân trang trên các tập dữ liệu.

+2

Rất đẹp. Tại sao nó phức tạp này để có được số hàng từ JSF datatable? Những người duy trì JSF ghét tất cả các nhà phát triển khác và họ đang cố gắng làm cho nó khó khăn? –

18

Giải pháp này đã được đăng bởi Jamie Williams trên CodeRanch. Anh ta nói nó hoạt động với Tomahawk. Tôi đang sử dụng các nguyên tố, cũng hỗ trợ nó.

<t:dataTable rowIndexVar="row" value="#{someBean.value}"> 
    <h:column> 
     <h:outputText value="#{row + 1}"/> 
    </h:column> 
</t:dataTable> 
+3

Bình luận của Ursula: "Cảm ơn bạn đã sử dụng giải pháp rowIndexVar Tôi đang sử dụng JSF 1.2 và myFaces, nó chỉ hoạt động mà không có dấu cách trong hàng + 1 ' '" –

4

Trong RichFaces có một giải pháp tương tự để Brent của:

<rich:dataTable value="#{backingBean.list}" var="v" rowKeyVar="index"> 
    <rich:column> 
     <f:facet name="header">Index</f:facet> 
     <h:outputText value="#{index + 1}" /> 
    </rich:column> 
    <rich:column> 
     <f:facet name="header">Name</f:facet> 
     <h:outputText value="#{v.name}" /> 
    </rich:column> 
</rich:dataTable> 
0

này đã làm việc hình thành tôi

<h:dataTable var="item" value="#{controller.items}"> 
    <h:column>#{controller.items.indexOf(item)}</h:column> 
    <h:column>value</h:column> 
</h:dataTable> 
0

tôi chỉ đơn giản phụ thuộc vào danh sách và vị trí của var trong danh sách này:

<h:column> 
      <f:facet name="header">#</f:facet> 
      #{bean.listValue.indexOf(varObject)+1} 
</h:column> 
Các vấn đề liên quan