Có một số cách để đạt được yêu cầu.
Nếu servletcontainer của bạn hỗ trợ tối thiểu Servlet 3.0 / EL 2.2, thì chỉ cần chuyển nó như một đối số của phương thức hành động / trình nghe của UICommand
thành phần hoặc AjaxBehavior
thẻ. Ví dụ
<h:commandLink action="#{bean.insert(item.id)}" value="insert" />
Kết hợp với:
public void insert(Long id) {
// ...
}
Điều này chỉ yêu cầu mô hình dữ liệu được giữ nguyên cho yêu cầu gửi biểu mẫu. Tốt nhất là đặt bean trong phạm vi xem bằng cách @ViewScoped
.
Bạn thậm chí có thể chuyển toàn bộ đối tượng item:
<h:commandLink action="#{bean.insert(item)}" value="insert" />
với:
public void insert(Item item) {
// ...
}
Trên các thùng chứa Servlet 2.5, điều này cũng có thể thực hiện được nếu bạn cung cấp triển khai EL hỗ trợ điều này, chẳng hạn như JBoss EL. Để biết chi tiết cấu hình, hãy xem câu trả lời này .
Sử dụng <f:param>
trong UICommand
thành phần. Nó thêm một tham số yêu cầu.
<h:commandLink action="#{bean.insert}" value="insert">
<f:param name="id" value="#{item.id}" />
</h:commandLink>
Nếu bean của bạn là phạm vi yêu cầu, hãy để JSF đặt nó bằng @ManagedProperty
@ManagedProperty(value="#{param.id}")
private Long id; // +setter
Hoặc nếu bean của bạn có phạm vi rộng hơn hoặc nếu bạn muốn xác thực / chuyển đổi chi tiết hơn, hãy sử dụng <f:viewParam>
trên chế độ xem đích, xem thêm f: viewParam vs @ManagedProperty :
<f:viewParam name="id" value="#{bean.id}" required="true" />
Dù bằng cách nào, điều này có lợi thế là mô hình dữ liệu không nhất thiết phải được lưu giữ cho biểu mẫu gửi (đối với trường hợp bean của bạn là phạm vi yêu cầu).
Sử dụng <f:setPropertyActionListener>
trong UICommand
thành phần. Ưu điểm là điều này loại bỏ nhu cầu truy cập bản đồ tham số yêu cầu khi bean có phạm vi rộng hơn phạm vi yêu cầu.
<h:commandLink action="#{bean.insert}" value="insert">
<f:setPropertyActionListener target="#{bean.id}" value="#{item.id}" />
</h:commandLink>
Kết hợp với
private Long id; // +setter
Nó sẽ chỉ có sẵn theo id
phương thức thuộc tính trong hành động. Điều này chỉ yêu cầu mô hình dữ liệu được giữ nguyên cho yêu cầu gửi biểu mẫu. Tốt nhất là đặt bean trong phạm vi xem bằng cách @ViewScoped
.
Ràng buộc giá trị có thể dữ liệu DataModel<E>
thay vào đó sẽ bao bọc các mục.
<h:dataTable value="#{bean.model}" var="item">
với
private transient DataModel<Item> model;
public DataModel<Item> getModel() {
if (model == null) {
model = new ListDataModel<Item>(items);
}
return model;
}
( transient
bắt buộc tạo nó và khởi tạo nó một cách lười biếng trong getter khi bạn đang sử dụng nó trên một bean phạm vi chế độ xem hoặc phiên vìDataModel
không triển khai Serializable
)
Sau đó, bạn sẽ có thể truy cập hàng hiện tại DataModel#getRowData()
mà không cần chuyển bất kỳ thứ gì xung quanh (JSF xác định hàng dựa trên tên tham số yêu cầu của liên kết / nút lệnh đã nhấp).
public void insert() {
Item item = model.getRowData();
Long id = item.getId();
// ...
}
Điều này cũng yêu cầu mô hình dữ liệu được giữ nguyên cho yêu cầu gửi biểu mẫu. Tốt nhất là đặt bean trong phạm vi xem bằng cách @ViewScoped
.
Sử dụng Application#evaluateExpressionGet()
để đánh giá dòng điện theo chương trình #{item}
.
public void insert() {
FacesContext context = FacesContext.getCurrentInstance();
Item item = context.getApplication().evaluateExpressionGet(context, "#{item}", Item.class);
Long id = item.getId();
// ...
}
Việc lựa chọn cách nào phụ thuộc vào các yêu cầu chức năng và liệu cách này hay cách khác mang lại nhiều lợi thế hơn cho các mục đích khác. Cá nhân tôi sẽ tiếp tục với # 1 hoặc, khi bạn cũng muốn hỗ trợ các thùng chứa servlet 2.5, với # 2.