1. 用隊列控制 Event Traffic
1) 以下兩個屬性用來避免由頻繁的 DHTML 事件所引發大量的 request 請求。
· eventsQueue
· requestDelay
2) 對于能夠引發 Ajax Request 的 4 種控件來說,以上兩種屬性都是可用的。
3) eventQueue 屬性
· 将 eventQueue 屬性指定一個對列名,則在目前一個 Request 被 Server 處理而 Response 還未被發回之前,下一個 Request 都将停留在隊列裡,以等待 Response 被發回。
· 隊列裡總保持隻有一個待發的 Request ,所有後續的 Request 都會将前面未發的 Request 清除掉。
比如,當你在 <a4j:support event=”onkeyup”> 的文本框中輸入第一個字元‘ a ’,則第一個 Request 會被立即發到 Server ,但在 Response 被發回之前,你又輸入了‘ b ’,則文本框裡的值變為‘ ab ’,但這個 Request 隻能等待第一個 Response 被發回來以後才能被送出。而此時,你又輸入了第三個字元‘ c ’,則‘ abc ’的 Request 就回把隊列裡還沒來得及發出去的‘ ab ’的 Request 清除掉。此時,第一個 Response “終于”回來了,則‘ abc ’的 Request 才被順利的發出去。
· 大緻測試了一下,當多個控件将隊列名都設為同一個的時候,比如 eventsQueue = fooQueue ,控件之間的 Request 不會互相幹擾,也就是說控件 B 的新的 Request ,并不會把同一隊列中控件 A 的未發的舊 Request 清除掉。
4) requestDelay 屬性
· 機關毫秒 ms ,用來定義 Request 被發送出去之前,需要在隊列裡強制等待的時間。即使前面一個 Request 都沒有,也必須老老實實等着到點。
· 可以将 eventsQueue 和 requestDelay 一起使用。
5) ignoreDupResponse 屬性
· 将此屬性設為 true ,則當同一控件發出新的 Request 的時候,目前的 Response 将被 Ajax 忽略掉。
注意,之前的 Request 在 Server 上已經被處理,隻是 Response 在 Client 上被忽略掉了。
· eventsQueue 和 ignoreDupResponse 的差別在于:
前者的 Response 總是會被 Client 處理,然後隊列中的 Request 才被發出,屬于“先來後到”;而對于後者來說,一旦發現同一控件又有了新的 Request ,則立即抛棄現有的 Response ,屬于“喜新厭舊”。
· 如果設定了 ignoreDupResponse 而沒有設定 eventsQueue ,則系統會根據控件的 ID 建立一個預設的事件隊列。
2. JavaScript 互動
1) 調用自定義的 JavaScript 函數
盡管使用 RichFaces 時不用寫 JavaScript ,但 RichFaces 仍然允許你調用自定義的 JavaScript 函數。
· onsubmit :僅當 Ajax Request 被發送之前;
· onbeforedomupdate :僅當 DOM 更新被處理之前;
· oncomplete : 當 DOM 更新被處理完畢之後。
2) data 屬性
· 可以從 Server 上得到任何額外的資料,可以通過 EL 表達式簡單地将 data 屬性指向 bean property ,然後資料将會按照 JSON 的格式串行化到用戶端。比如:
<a4j:commandButton value="Submit" reRender="out"
data="#{bean.text}" oncomplete="alert(data)"/>
· 除了基礎類型,其他可以被串行化的複雜類型(數組、集合),也可以加入 JSON 格式。
3. 性能方面的考慮
1) 使用 eventsQueue 和 requestDelay
2) 使用 bypassUpdate 屬性
當此屬性設為 true 的時候, Update Model 和 Invoke Application 階段将會被跳過,進而縮短響應時間。通常用在表單驗證上。
3) 使用 <a4j:region>
· 當 renderRegionOnly 屬性被設為 true 時, Browser 将隻重新整理目前 Region ,也就是發出 Ajax Request 的 Region 。對于 Region 以外的, Partial-Page 重新整理将不會被處理。
· 當 renderRegionOnly 屬性被設為 true 時,隻有同時 滿足以下兩點的部分會被重新整理:
控件必須在引發 Ajax Request 的 Region 裡;
被設定為需要重新整理(在目前 Region 的其他控件的 reRender 裡或者在 <a4j:outputPanel ajaxRendered=”true”> 裡)。
其他的部分一概不會被重新整理。
· selfRendered 屬性
4. 驗證使用者輸入(執行個體)
1) 使用 <a4j:region> 或者 ajaxSingle 屬性來限制 process 的 Region ,以避免控件間互相幹擾。
2) 使用 <rich:message> 來顯示錯誤資訊。
3) 使用 <a4j:region> 以及 renderRegionOnly 屬性,而不是 ajaxSingle ,來避免錯誤資訊被其他控件的單獨 process 而被清除掉。
4) 使用 bypassUpdate 屬性來跳過 Update Model 和 Invoke Application 階段。
5. 使用 <a4j:actionparam>
1) <a4j:actionparam> 可以被認為是 <f:param> 和 <f:actionListener> 的組合:
· <f:param> - 在 request 中傳遞參數;
· <f:actionListener> - 設定 Bean property 的值。
2) 與 <f:setPropertyActionListener> 非常相似:
· value 對應 value ;
· assignTo 對應 target ;
· name 、 converter 沒有對應。
【注意】因為需要向 request 傳遞參數,是以 name 屬性一定不能少。
3) 不同點:
· <a4j:actionparam> 向 request 傳參數,是以當要傳的不是 String 的時候,需要 Converter 的支援;而 <f:setPropertyActionListener> 是直接設定 Bean property ,是以它不需要指定 Converter 。
· <f:setPropertyActionListener> 因為是 <f:actionListener> 類的 ActionListener ,是以總比 actionListener 屬性類的方法調用的晚(《 JSF 核心程式設計》)。是以想用 <f:setPropertyActionListener> 給 actionListener 屬性類的方法傳遞資料,恐怕不可行。但 <a4j:actionparam> 兼具兩種功能,是以可以用作給 actionListener 屬性類的方法傳遞資料。
· <a4j:actionparam> 既可以給 <a4j:commandButton> 和 <a4j:commandLink> 傳遞參數,也可以給 <a4j:support> 傳遞參數。
6. 使用 <a4j:repeat>
1) <a4j:repeat> 與 <h:dataTable> 很相似,用法也接近。不同點在于 Ajax Request 之後 <a4j:repeat> 可以隻重新整理選中的行或列,而不必重新整理整個表格。
2) <a4j:repeat> 的體可以包含多種代碼,從 JSF 控件到 HTML ,不一而足。
3) 使用 ajaxKeys 屬性對選中列或行進行部分重新整理
【注意】通過 reRender 重新整理的控件,必須確定它能生成一些标記 markup ;如果元件不生成任何 markup 或者 rendered 設為 false ,則應該将其置于 PlaceHolder 中,比如 <h:panelGrid> 或者 <a4j:outputPanel> 。
· 基本屬性:
value 、 var 與 <h:dataTable> 相同;
rowKeyVar 代表行号的變量名, String 類型。
· ajaxKeys 屬性,指向一個 java.util.Set 對象,其中包含着需要被重新整理的行号,從 0 開始計數,接受 EL 表達式;
· 每一行裡引發 Ajax Request 的控件的 reRender 屬性決定哪些列要被重新整理;而 ajaxKeys 決定哪些行要被更新。這兩個屬性精确定位了需要重新整理的“單元格”,進而實作頁面的部分刷 新。
<rich:panel header="a4j:repeat Test">
<table>
<a4j:repeat value="#{nameListBean.nameList}" var="name"
rowKeyVar="rowNo" ajaxKeys="#{nameListBean.rowsToUpdate}">
<tr>
<td>
<h:outputText value="#{rowNo}"></h:outputText>
</td>
<td>
<h:outputText id="fullName" value="#{name.fullName}"></h:outputText>
</td>
<td>
<h:inputText id="firstName" value="#{name.firstName}">
<a4j:support event="onblur"
actionListener="#{nameListBean.refreshRowsToUpdate}"
reRender="fullName">
<a4j:actionparam name="rowNo" value="#{rowNo}"
assignTo="#{nameListBean.currentRow}"/>
</a4j:support>
</h:inputText>
</td>
<td>
<h:inputText id="lasttName" value="#{name.lastName}">
<a4j:support event="onblur"
actionListener="#{nameListBean.refreshRowsToUpdate}"
reRender="fullName">
<a4j:actionparam name="rowNo" value="#{rowNo}"
assignTo="#{nameListBean.currentRow}"/>
</a4j:support>
</h:inputText>
</td>
</tr>
</a4j:repeat>
</table>
</rich:panel>
7. 使用 <a4j:status>
1) <a4j:status> 可以用來顯示 Ajax Request 發送和結束的狀态。
2) 可以引發 Ajax Request 的那四個 <a4j> 控件都可以通過‘ status ’屬性來指定 <a4j:status> 控件。
3) <a4j:status> 也可以被指定給 Region 。
4) <a4j:status> 的主要屬性:
· startText 和 stopText
· <f:facet name=”start”> 和 <f:facet name=”stop”> ,任何 JSF 控件都可以加進來,包括 GraphicImage
5) 将 Status 指定給 Region
· 無需特别操作,隻将 <a4j:status> 放在 Region 内即可;
· <a4j:status> 隻為所在的 Region 服務,所在 Region 内部或外部的 Region 都不服務;
· <a4j:status> 也可以用其自身的 left 、 top 等屬性精确定位。
8. 使用 <a4j:include> 和 <a4j:keepAlive>
1) 可以使用 <a4j:include> 在父 View 中包含子 View ,而子 View 仍然可以像正常 JSF 一樣,按照導航規則導航。通常用來做向導之類的頁面。
2) <a4j:include viewId="/step1.xhtml"/> 可以被放置于頁面的任何位置。
【注意】 viewId 屬性應該以“ / ”開頭。
3) 在 faces-config.xml 中為子 View 定義導航規則, <from-view-id> 應該是子 View 的 view id 。
4) 使用 <a4j:keepAlive>
· 可以使 requestScope 的 bean 的生命長于 request 而又短于 Session ;
· name 屬性指向 managed bean 的名字,而不是 EL 表達式;
· 原理在于, name 屬性所指向的 bean ,在頁面 render 之前被存儲;當下一個 Request 到來時, bean 又被倒回 request ,而其之前的值仍然可用。
· 預設情況下, <a4j:keepAlive> 也可以為非 Ajax 請求服務;要想限制其隻為 Ajax Request 服務,則要将其 ajaxOnly 屬性設為 true 。
9. 使用 <a4j:jsFunction>
1) <a4j:jsFunction> 與其他四種可以引發 Ajax Request 的控件非常相似;不同點在于 <a4j:commandButton> 、 <a4j:support> 是通過 DHTML event 引發 Ajax Request ,而 <a4j:jsFunction> 是通過自定義的 JavaScript 函數來引發 Ajax Request 。當自定義 JavaScript 函數被調用的時候, Ajax Request 被引發。
2) <a4j:jsFunction> 也包含 action 、 actionListener 、 reRender 等屬性,也可以包含 <f:param> 或 <a4j:actionparam> 。
3) <a4j:jsFunction> 也可以像 <a4j:commandButton> 一樣作為獨立控件使用,而不是像 <a4j:support> 一樣。
10. 使用 <a4j:ajaxListener>
1) 該 Listener 隻在 Render Response 階段被調用,是以它總是會被調用到,不會被跳過。
2) 該 Listener 隻為 Ajax Request 所調用。
3) 通常用來檢查或設定需要被 render 的控件。