2014年2月26日水曜日

PlayFrameworkで会員制ギャラリーサイトを作る習作:2ページ目以降をAjaxで取得する

それでだ、
Play Frameworkで会員制ギャラリーサイトを作っている途中。
前回のところでデータを取ってきて表示するところまで行きました。
app/views/ajax/listAjax.scala.html今回は画面をスクロールしたら2ページ目、3ページ目が読み込まれるところの処理を作っていきます。

なお、今回からTypesafe Activatorでアプリケーションを起動させるのはやめました。だって、play cleanがされなくて改修前の実装コードが残ってしまうのだもの・・・・。
すなおに play debug runするようにしました。

さて、2ページ目以降を取得する処理です。

https://github.com/YoshiteruIwasaki/PlayFrameworkRecruitConsole/commit/5756fc962c1ef328e3020beb0b92d5e20c3a3b51

のコミットが全てなのですが、処理の流れを見て行きましょう。

まずはCntroller


app/controllers/ajax/ListAjaxController.java
にしました。なおパッケージ名はcontrollers/ajax/***とかcontrollers/api/*** とかのように、共通するレスポンス形式とかでまとめておいたほうが後々フィルタをかけて処理させるときとかに楽になります。

1Action1Controllerファイルくらいにしておくと大規模開発にも耐えられるようになります。(コンフリクトが起きにくくなるという意味で)

1Controllerに入れていいのはせいぜいフォームの入力・確認・完了処理くらいまでかと思います。あとは分けましょう。
デメリットとしてはコンパイルが遅くなります。
ちなみにajax/ListAjaxController.javaの名前の付け方はイケてないです。

中身の処理は引数をページ番号としてまあ結果一覧を取得して返すだけの処理です。
 
public static Result index(int page) {
   List<SiteBean> resultList = SiteBeanService.getSiteBeanResultList(page);
   return resultList.size() == 0 ? ok("") : ok(views.html.ajax.listAjax
     .render(page, resultList));
  }

テンプレートでは面倒なのでhtmlを返しています。
JSONで返して、Javascript側でゴニョゴニョしてもいいかと思います。

conf/routes
にルーティングの設定を追加しておきましょう。
 
GET     /listAjax/:page                           controllers.ajax.ListAjaxController.index(page:Integer)

次にテンプレートから呼び出す方法


さて、最初の画面を表示して2ページ目以降を取得する処理ですが、
jquery_bottom
を利用してアクションを呼び出すようにします。

ページのフッターに次に呼ぶページ番号と更に読み込むページがあるかのフラグ用の値をセットしておきます。
 
<input type="hidden" id="hasNext" value="0" />
<input type="hidden" id="page" value="1" />


あとは呼び出す処理が呼ばれた際の中身を書いていきます。

 
 $(window).on('bottom', function() {
  var obj = $(this);
  // since this ajax call might take a while
  if (!obj.data("loading") && $("#hasNext").val() == 0) {
   obj.data("loading", true);
   $("#loading").show();
   $.ajax({
    url : "/listAjax/" + $("#page").val(),
    dataType : "html",
    success : function(data) {
     if (data == "") {
      $("#hasNext").val(1);
     } else {
      $("#listContainer").append(data);
     }
     var page = parseInt( $("#page").val() );
     $("#page").val(page + 1);
     // remove the loading text
     $("#loading").hide();
     // now that the ajax call is done, we can re-enable this
     obj.data("loading", false);
     $("#list"+page).preloader();
    },

    error : function(data) {
     console.log(data);
    }
   });
  }
 });


  1. 次に呼び出すページがあるようであればページ番号を渡してAjaxリクエスト
  2. レスポンスが空だったら処理終わりのフラグを立てて終了
  3. レスポンスがあったら帰ってきたレスポンスのhtmlをappendして表示
  4. ページ番号を1追加する
  5. ローディングを隠す
  6. 画像をかっこ良く表示させるpreloaderを呼ぶ

みたいなことをやっています。

0 件のコメント:

コメントを投稿