<F: siêu dữ liệu>, <f: viewParam> và <f: viewAction> có thể được sử dụng để làm gì?


149

Bất cứ ai cũng có thể làm rõ làm thế nào chúng ta có thể sử dụng nói chung, hoặc một ví dụ trong thế giới thực, đoạn trích này?

<f:metadata>
    <f:viewParam id="id" value="#{bean.id}" />
    <f:viewAction action="#{bean.init}" />
</f:metadata>

Câu trả lời:


288

Xử lý các tham số GET

Việc <f:viewParam>quản lý cài đặt, chuyển đổi và xác nhận các tham số GET. Nó giống như <h:inputText>, nhưng sau đó cho các tham số GET.

Ví dụ sau

<f:metadata>
    <f:viewParam name="id" value="#{bean.id}" />
</f:metadata>

về cơ bản như sau:

  • Lấy giá trị tham số yêu cầu theo tên id.
  • Chuyển đổi và xác nhận nó nếu cần thiết (bạn có thể sử dụng required, validatorconvertercác thuộc tính và tổ một <f:converter><f:validator>trong nó giống như với <h:inputText>)
  • Nếu chuyển đổi và xác thực thành công, thì hãy đặt nó làm thuộc tính bean được biểu thị bằng #{bean.id}giá trị hoặc nếu valuethuộc tính vắng mặt, sau đó đặt nó làm yêu cầu attribtue trên tên idđể nó có sẵn #{id}trong chế độ xem.

Vì vậy, khi bạn mở trang foo.xhtml?id=10sau đó, giá trị tham số 10được đặt theo bean theo cách này, ngay trước khi chế độ xem được hiển thị.

Khi xác thực, ví dụ sau đặt tham số required="true"và chỉ cho phép các giá trị trong khoảng từ 10 đến 20. Bất kỳ lỗi xác thực nào cũng sẽ dẫn đến thông báo được hiển thị.

<f:metadata>
    <f:viewParam id="id" name="id" value="#{bean.id}" required="true">
        <f:validateLongRange minimum="10" maximum="20" />
    </f:viewParam>
</f:metadata>
<h:message for="id" />

Thực hiện hành động kinh doanh trên các tham số GET

Bạn có thể sử dụng <f:viewAction>cho việc này.

<f:metadata>
    <f:viewParam id="id" name="id" value="#{bean.id}" required="true">
        <f:validateLongRange minimum="10" maximum="20" />
    </f:viewParam>
    <f:viewAction action="#{bean.onload}" />
</f:metadata>
<h:message for="id" />

với

public void onload() {
    // ...
}

Các <f:viewAction>là tuy nhiên mới kể từ JSF 2.2 ( <f:viewParam>đã tồn tại kể từ khi JSF 2.0). Nếu bạn không thể nâng cấp, thì cách tốt nhất của bạn là sử dụng <f:event>thay thế.

<f:event type="preRenderView" listener="#{bean.onload}" />

Điều này tuy nhiên được viện dẫn theo mọi yêu cầu. Bạn cần kiểm tra rõ ràng nếu yêu cầu không phải là một postback:

public void onload() {
    if (!FacesContext.getCurrentInstance().isPostback()) {
        // ...
    }
}

Khi bạn muốn bỏ qua các trường hợp "Chuyển đổi / Xác thực không thành công", hãy thực hiện như sau:

public void onload() {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    if (!facesContext.isPostback() && !facesContext.isValidationFailed()) {
        // ...
    }
}

Sử dụng <f:event>cách này về bản chất là một cách giải quyết / hack, đó chính xác là lý do tại sao nó <f:viewAction>được giới thiệu trong JSF 2.2.


Truyền tham số cho chế độ xem tiếp theo

Bạn có thể "chuyển qua" các tham số xem trong các liên kết điều hướng bằng cách đặt includeViewParamsthuộc tính truehoặc bằng cách thêm includeViewParams=truetham số yêu cầu.

<h:link outcome="next" includeViewParams="true">
<!-- Or -->
<h:link outcome="next?includeViewParams=true">

tạo ra với <f:metadata>ví dụ trên về cơ bản liên kết sau

<a href="next.xhtml?id=10">

với giá trị tham số ban đầu.

Cách tiếp cận này chỉ đòi hỏi rằng next.xhtmlcũng một <f:viewParam>trên tham số rất giống nhau, nếu không nó sẽ không được đi qua.


Sử dụng các biểu mẫu GET trong JSF

Cũng <f:viewParam>có thể được sử dụng kết hợp với các biểu mẫu GET "HTML đơn giản".

<f:metadata>
    <f:viewParam id="query" name="query" value="#{bean.query}" />
    <f:viewAction action="#{bean.search}" />
</f:metadata>
...
<form>
    <label for="query">Query</label>
    <input type="text" name="query" value="#{empty bean.query ? param.query : bean.query}" />
    <input type="submit" value="Search" />
    <h:message for="query" />
</form>
...
<h:dataTable value="#{bean.results}" var="result" rendered="#{not empty bean.results}">
     ...
</h:dataTable>

Với cơ bản là @RequestScopedđậu này :

private String query;
private List<Result> results;

public void search() {
    results = service.search(query);
}

Lưu ý rằng đó <h:message>là dành cho <f:viewParam>, không phải là HTML đơn giản <input type="text">! Cũng lưu ý rằng giá trị đầu vào hiển thị #{param.query}khi #{bean.query}trống, bởi vì giá trị được gửi sẽ hoàn toàn không hiển thị khi có lỗi xác thực hoặc chuyển đổi. Xin lưu ý rằng cấu trúc này không hợp lệ đối với các thành phần đầu vào của JSF (nó đã thực hiện "dưới vỏ bọc" rồi).


Xem thêm:


@BalusC Phạm vi của "bean" phải là gì khi được sử dụng cùng với các mặt-redirect = true? Nó có hoạt động như mong đợi không nếu phạm vi được đặt thành "@RequestScoped"?
Geek

@Geek: Chuyển hướng tạo một yêu cầu GET mới. Phạm vi bean của nguồn và bean đích là không liên quan. Tuy nhiên, bạn nên xem xét các tác động có thể có của một yêu cầu GET mới cho một yêu cầu và xem đậu có phạm vi. Xem thêm stackoverflow.com/questions/7031885/
Mạnh

@BalusC Chính xác ý của bạn là gì bởi "Tuy nhiên, bạn nên sử dụng các hàm ý có thể có của một yêu cầu GET mới cho một yêu cầu và xem đậu có phạm vi."
Geek

@Geek: Chúng sẽ được chuyển vào thùng rác và được tạo lại bởi vì phạm vi của chúng sẽ kết thúc và bắt đầu.
BalusC

@BalusC. Một câu trả lời toàn diện. "Khi bạn cần sử dụng tính năng '@' PostConstruct like để xem các loại đậu có phạm vi không được gọi trong mỗi yêu cầu, hãy kiểm tra xem yêu cầu đó có phải là một postback không". Nếu nó không được yêu cầu trên mỗi yêu cầu thì tại sao phải kiểm tra xem yêu cầu đó có phải là một postback hay không?
Uluk Biy
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.