天天看點

[Java EE 7] JSF 中的 Ajax

JSF 支援頁面的 Ajax 處理。可以支援局部頁面處理和局部頁面展示。

JSF 中的 Ajax 通過下面兩個途徑:

[list]

[*] 通過 JavaScript 編碼實作

[*] 通過 f:ajax 以聲明方式實作

[/list]

先看看使用 JavaScript 如何實作。 jsf.js 是在 javax.faces 庫中的預定義資源。這個 JS 包含了 JSF 頁面支援 Ajax 的 API。在頁面中引用需要用到 outputScript 标簽:

<h:body>
<!-- . . . -->
<h:outputScript 
    name="jsf.js" 
    library="javax.faces" 
    target="body"/>
<!-- . . . -->
</h:body>
           

現在,可以向伺服器發起一個異步請求了:

<h:form prependId="false">
  <h:inputText value="#{user.name}" id="name"/>
  <h:inputText value="#{user.password}" id="password"/>
  <h:commandButton value="Login" 
                   type="button"
                   actionListener="#{user.login}"
     onclick="jsf.ajax.request(this, event, {execute: 
'name password', render: 'status'}); return false;"/>

  <h:outputText value="#{user.status}" id="status"/>
</h:form>
           

在這段代碼中:

兩個文本輸入框用于輸入使用者名和密碼。一個文本輸出控件用于展示使用者登入狀态。

form 中的 prependId 屬性設定為 false,用于確定表單中的元素 id 以目前的形式儲存。否則,會在元素 id 前面加上 form 的 id。

按鈕的 actionListener 屬性用于設定點選按鈕的時候,背景 bean 調用的方法。現在取代傳統的重新整理頁面展示,jsf.ajax.request 發送了一個異步請求到伺服器,這個請求在按鈕的 onclick 事件中産生。execute 和 render 屬性值是用空格分隔的元件 id。execute 中的元件是輸入元件,将會将元件中的值綁定到背景 bean。render 中的元件是展示元件,用于設定收到異步響應後需要重新整理的元件。

下表列出了 render 屬性可以設定哪些值:

[table]

|值| 描述|

|@all| 頁面上的所有元件|

|@none| 無元件,這是預設值|

|@this| 觸發請求的元件|

|@form| form 表單中的所有元件|

|ID 清單| 元件 ID 的清單|

|EL 表達式| 傳回一組 String 清單的 EL 表達式|

[/table]

execute 屬性的值和 render 屬性的值類似,不過預設值換成了 @this。

編寫一個 User bean,包含 set、get 方法和簡單的業務邏輯:

@Named
@SessionScoped
public class User implements Serializable {
    private String name;
    private String password;
    private String status;
    public void login(ActionEvent evt) {
        if (name.equals(password))
            status = "Login successful";
        else
            status = "Login failed";
    }
}
           

注意 login 方法,它必須使用 javax.faces.event.ActionEvent 作為它的唯一參數。

聲明是 Ajax 可以使用 f:ajax。這個标記可以作用于一個元件,也可以作用于多個元件。

上面的代碼可以改寫為:

<h:form prependId="false">
       <h:inputText value="#{user.name}" 
                    id="name"/>
       <h:inputText value="#{user.password}" 
                    id="password"/>
       <h:commandButton value="Login" 
                        type="button"
                        actionListener="#{user.login}">
           <f:ajax execute="name password" 
                      render="status"/>
    </h:commandButton>

    <h:outputText value="#{user.status}" 
                  id="status"/>
</h:form>
           

在這段代碼中,使用了 f:ajax 中的 execute 屬性指定輸入參數,render 屬性指定顯示參數。預設情況下,如果 f:ajax 用在一個元件上,并且沒有指定 event 事件,那麼異步請求将會基于它的父元件的預設事件(在這個例子中,父元件是送出按鈕)。

可以在 f:ajax 上設定 delay 屬性,屬性值是毫秒數,用于設定延遲送出的時間。如果在延遲時間到期前有多個請求,那麼隻會送出最近的那個請求,其它的請求将會被丢棄。

<f:ajax delay="200" ...>
  . . .
</f:ajax>
           

這段代碼設定了延遲時間為 200 毫秒,預設是 300 毫秒,但是你可以設定值為 none 來關閉這個功能。

f:ajax 标簽中可以包含多個元件:

<f:ajax listener="#{user.checkFormat}">

<h:inputText value="#{user.name}" id="name"/>

<h:inputText value="#{user.password}" id="password"/>

</f:ajax>

在這段代碼中,f:ajax 有一個 listener 屬性用于指定相關的方法:

public void checkFormat(AjaxBehaviorEvent evt) {
    //. . .
}
           

這個 listener 中的方法将會是所有子元件的預設方法(在這個例子中是 h:inputText 的 valueChange 事件的預設方法),如果你要改變子元件的預設方法,可以在子元件中使用 a:ajax 标簽。

文章來源:[url]http://www.aptusource.org/2014/04/java-ee-7-jsf-ajax/[/url]