JSFでajaxを使うときにいろいろと調べたのでメモ。
やろうとしたことはWEB上で給与明細の計算をしたくて、プルダウンで月の変更したら自動的に経費が該当月に替わるというシステムです。
ajaxを使うときの考え方ですが、基本的には
- トリガー
- 送信コンポーネント
- メソッド
- レンダー
に注意します。
1.トリガー
ようはどのイベントが起こった時に通信が発生するかという起点になる動きのことです。
<f:ajax>の部分がajaxのタグを記述する場所になります。
ソースは該当月の部分のみです。
1 2 3 4 |
<h:selectOneMenu value="#{menuBean.targetDate}" > <f:selectItems value="#{menuBean.targetMonthPullDown}" /> <f:ajax event="change" execute="@this" listener="#{menuBean.setExpenseData() }" render="@form" /> </h:selectOneMenu> |
このeventとという部分がトリガーになります。今回はプルダウンを変更したら~という設定にしてあります。
トリガーとなるイベントは通常のJavaScriptのイベントであれば大体大丈夫かと思います。
2.送信コンポーネント
次はトリガーが起こった時にどのデータをCDI側に送るかです。executeで指定します。
今回は該当月のみ(自分自身)なので@thisとしてありますが、下記のような送信方法があります。
- 全体・・@all
- form内全体・・@form
- 送らない・・@none
- 自分自身・・@this
- idの場合にはexecute=”sample_id sample_id2″などスペースを空けて指定。
3.メソッド
listenerに記述。ここでCDIのメソッドを呼ぶことができます。
またAjaxを使うときはスコープをRequestではなくViewにしたほうがよいでしょう。
RequestだとイベントのたびにCDIが初期化されますがViewであれば該当メソッドだけ呼ばれるため、その分処理が速くなります。
4.レンダー
ここがJSFのポイントなんですが、CDIのプロパティが変わっても自動的に画面側の値は変わりません!
どの値をレンダリングさせるか?ということを指定してあげないといけないんですね。
これで結構時間食いました。CDIの値がしっかり変わっているのに画面の値が変わらない・・・
どの値を反映させるかがrenderになります。
ちなみに指定方法はexecuteと同じになります。
番外
ajax反映後のjquery
給与明細には経費の詳細を見れるようにボタンにトリガーを付けておいたのですが、ajax反映後変化しないというバグが起こりました。
そういえば昔、ajaxで追加したテーブルはjqueryが起動しませんでしたね・・・
解決手段ですが、下記のように記述しておけば無事起動します。
1 2 3 |
$(document).on('イベント',"セレクタ", function () { //一連の処理 }); |
下記リンクを参考にしました。
jQueryで後から追加した要素へのclickイベントはonを使う
追記
ちなみにajaxはクロスドメイン(ドメインが違うもの)のものを読み込んだり、アクセスしたりはできません。
jqueryを外部のURLから読み込んだ時にこの問題が起きるので注意しましょう。(ブラウザのコンソール機能でみるとわかりやすい。)
続 クロスドメインで使う XMLHttpRequest と CORS の話
AjaxでAccess-Control-Allow-Originのエラーを回避する方法