2012年09月

dojoするなら!:ajaxって表示してみよう(2)

今回のテーマ

他のライブラリと同様、dojoにも生のjavascriptでは実装が面倒な部分を 簡単にしてくれる便利な関数がそろっています。これを利用することで、ブラウザ互換の問題を意識することなくプログラミングしていくことができます。ありがたや。

今回はそれら関数の使い方、プラス、dojoが誇る美麗なUIで表示する方法についてです。

やってみましょう

作るプログラムは前回の続きですよ。ajaxで持ってきた選手のjsonデータを良い感じに処理して、 ダイアログにその内容を単純に表示するまで、です。 次のステップの説明をします。

  1. 便利関数たち
  2. ダイアログの表示

便利関数たち

この表を みてもらうと、どんな関数があるかわかります。ajaxやDOM/HTML関連のもの(前回やりましたね)、cookieやdrag&drop関連のものなどいろいろあります。あるといいなは、だいたいあるかと思います。

使い方は前回ajaxの関数を使いましたが、流れはそれと同じです。使いたい関数を含むモジュールをまずrequireして、それからその関数を呼び出します。

今回は、選手情報の入った連想配列をイテレータで値を順に処理しつつ、HTMLのテンプレートにそれらの値をはめ込んで返す処理をしてみます。

require([
    "dojo/_base/array",
    "dojo/string",
    "dojox/html/entities"
], function(arrayUtil, string, htmlent){
    // テストデータ
    var _data = [
        { num: 23, name: "山田 栄治"},
        { num: 16, name: "ポール・<b>サンダー</b>・ワット"},
        { num: 33, name: "飯田 宏"}
    ], _content = "";

    // イテレータはarrayのforEach関数
    arrayUtil.forEach(_data, function(item) {
        // テンプレート的にデータをはめ込む
        _content += string.substitute(
            "<div>背番号:${num},氏名:${name}</div>", item,
            function(arg) {
                // substituteの第三引数は、テンプレートに
                // はめ込む前に実行する関数
                // ここでは、htmlのタグをエスケープする処理
                // (dojox/html/entities/encode)を行う
                return htmlent.encode(""+arg);
            });
    });
    
    // 結果
    console.log(_content);
});

どうですか!生のjavascriptでやろうと思ったらうんざりしますよね。ちなみに実行結果はこうなります。
12
 

これまでのレガシーなdojoでは、便利関数たちは「dojo.xxx」で使うことができました。例えばforEachを使いたければ、特に何かをrequireすることなく、dojo.forEachと書くだけでした。

モダンなdojoでは、

forEach使いたいけど、これは何のモジュールだっけ?
あぁ、dojo/_base/arrayね。じゃー、これをrequireしてっと。

という流れになります。面倒ですが、できるだけ標準でロードするモジュールを少なくしたい=速くしたいという気持がびんびんに伝わってきます。使いたい関数とモジュールの対応を覚えるまでは、慣れが必要ですね。

余談ですが、forEachについて。javascriptにもforEachがありますけど、dojoのforEachとは 配列に値がない場合の動きがちょっと違うんですよ。

require(
  ["dojo/_base/array"],
  function(arrayFunc){
    var test = [0, 1];
    test[3] = 3;

    console.log("配列");
    console.log(test);

    console.log("-------");
    console.log("javascriptのforEach");
    test.forEach(function(item){
      console.log(item);
    });

    console.log("-------");
    console.log("dojoのforEach");

    arrayFunc.forEach(
      test,
      function(item){
        console.log(item);
      }
    );
  }
);
実行結果
配列
[0, 1, undefined × 1, 3]
-------
javascriptのforEach
0
1
3
-------
dojoのforEach
0
1
undefined
3

ダイアログの表示

次はダイアログを表示してみます。コーディングの前に、美麗なUIを実現するスタイルの設定をしましょう。

まずは、stylesheetの読み込みです。これもgoogleさんのCDNにホスティングされてますね。

<link href="//ajax.googleapis.com/ajax/libs/
dojo/1.8/dijit/themes/claro/claro.css" rel="stylesheet">

URLにある"claro"ってなにかというと、dojoが用意しているスタイルのテーマになります。claroの他にtundra, nihilo, soriaの3種類用意されていて、それぞれフォント、色合いや文字サイズなどが違ってきます。

それぞれの違いはここで。 読み込んだテーマをbodyタグのclassに設定することで、ページ全体に適用します

<body class="claro">

この準備さえできれば、後はこれまでと同じです。ダイアログのモジュールをrequireして、その関数を呼び出すだけです。

require(["dijit/Dialog"],  //ダイアログのモジュールはdijit/Dialogにあります。
  function(Dialog){
    // タイトル・スタイル・中身を設定して・・・
    var _dialog = new Dialog({
                    title:"選手一覧",          
                    style:"width:300px",       
                    content:"選手の情報を一覧にしました。" 
                  });
    // show()を呼ぶとダイアログが表示されます。
    _dialog.show()
  }
);
実行結果

32

ダイアログのパラメータについては、初期化するときだけではなく後から設定/変更することが可能です。

require(["dijit/Dialog"],  //ダイアログのモジュールはdijit/Dialogにあります。
  function(Dialog){
    // タイトル・スタイル・中身を設定して・・・
    var _dialog = new Dialog({
                    title:"選手一覧",          
                    style:"width:300px"
                  });

    // contentは後から設定
    _dialog.set("content", "選手の情報を一覧にしました。" );

    // show()を呼ぶとダイアログが表示されます。
    _dialog.show()
  }
);

まとめ

今回の一覧の流れを一つにするとつぎのようになりました。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>ajax sample</title>
    <link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.8/dijit/themes/claro/claro.css"></link>
    <script src="//ajax.googleapis.com/ajax/libs/dojo/1.8.0/dojo/dojo.js"
            data-dojo-config="async: true"></script>
    <script>
      
        require(
            [
                "dijit/Dialog",
                "dojo/on",
                "dojo/dom",
                "dojo/request",
                "dojo/_base/array",
                "dojo/string",
                "dojox/html/entities",
                "dojo/domReady!"
            ],
            function(Dialog, on, dom, request, arrayUtil, string, htmlent) {
        
                var _dialog = new Dialog({title:"プレーヤー一覧", style:"width:300px;"}),
                showDialog = function(dlg, data){
                        var _content = "";

                        arrayUtil.forEach(data, function(item){
                            _content += string.substitute("<div>背番号:${num},氏名:${name}</div>", item,
                                        function(d){return htmlent.encode(""+d);});
                        });

                        dlg.set("content", _content);
                        dlg.show();
                }

                on(dom.byId("show_dialog_button"), "click", function(evt){
                    request.get("./fighters.json", {handleAs:"json"})
                           .then(
                               function(data){
                                   showDialog(_dialog, data);
                               }, function(err){
                                   console.log(err);
                               });
                })
                
            });
    </script>
</head>
<body class="claro">
  <button type="button" id="show_dialog_button">show dialog</button>
</body>
</html>

実行結果
22

さり気なくクリックイベントの処理が入っていますが、まあ見ての通りですね(^^)

dojoするなら!:ajaxって表示してみよう(1)

1:はじめに

最近のリリースで"モダン"な書き方になったdojoですが、日本語のドキュメントがまだまだ多くはありません。 はじめての方も、"レガシー"な頃しか知らない方も、dojoでのプログラミングの雰囲気を味わってもらえればと思います。

2:今回のテーマ

今回は、dojoを使ってサーバのデータをajaxってデータを表示するまでを二回に分けて取り組みます。 題材として、次の機能を実装してみます。

リンクをクリックすると、サーバーから「ファイターズ外野手」のjsonデータを取得し、結果を成形してダイアログで表示

面白くはないですが...まぁ、まずは基本ってことで!

サーバーサイドは今回は範囲外なので、jsonファイルを同じディレクトリに配置するだけにします。 jsonファイルの中身はこんな感じ(ファイターズ公式サイトから作りました)

[{'num':'7','name':'糸井 嘉男','kana':'イトイ ヨシオ','pos':'外野手'},
{'num':'10','name':'ターメル・スレッジ','kana':'ターメル・スレッジ','pos':'外野手'}/*続く*/]

3:やってみましょう

次のステップの説明をします。

  1. dojoを使う準備:スクリプトの読み込みと書き方
  2. dojoを使う:お作法
  3. ajaxでのアクセス:request.getの使用
  4. 表示にdijitを使ってみる:ダイアログの表示,イベント処理(→次回)

3-1:dojoを使う準備

なにはなくても、dojoを使えるようにしましょう。他の有名ライブラリと同様、dojoもgoogleさんのCDNにホスティングされているので、ダウンロードや自サーバへの配置などの面倒はなくスクリプトタグ一発でロードできます。

<script src="//ajax.googleapis.com/ajax/libs/dojo/1.8.0/dojo/dojo.js"
data-dojo-config="async: true">

data-dojo-configはロードする時の設定条件を記述できます。asyncは、非同期ロードの設定です。falseなら、"base"となる関数を全て読み込むことになります。trueなら、ここでは必要最低限のロードにとどめ、後で必要なモジュールがでてきたらその時々にロードしましょうという意味になります。dojo高速化要因の一つですね。小さく産んで大きく育てるイメージでしょうか?違うか。

3-2:dojoを使う

ライブラリのロードができたので、次は実際にプログラムしてみましょう。先に述べたとおり、スクリプトをロードした段階では、便利なことはあまりできません。ajaxったり、domを操作したりということは、それぞれのモジュールを読み込まなくてはいけません。

レガシーなdojoでは、デフォルトで読み込まれるモジュールと後から読み込むモジュールが混在していました。たとえば、「ボタンを作って、それをある要素の子要素として追加する」場合、次のように書いていました。

//(dojoの)ボタンを使いたければ、dojo.requireでモジュールを読み込む
dojo.require("dijit.form.Button");

//こっからコーディング
var myButton = new dijit.form.Button({label:"click me!"});

// dojo.byIdは、document.getElementByIdをブラウザの差異を吸収
// してくれる便利関数のこと。
// これはdojo.requireしなくても使うことができる
dojo.byId("target_dom_id").appendChild(myButton.domNode);   

これがモダンになるとこうなります。

 //(dojoの)ボタンを使いたければ、requireでモジュールを読み込む
 require(["dijit/form/Button", "dojo/dom"], function(Btn, dom){
  //こっからコーディング
  var myButton = new Btn({label:"click me!"});

  // dom.byIdは、document.getElementByIdをブラウザの差異を
  //吸収してくれる便利関数のこと。
  //これはrequireの第一引数で"dojo/dom"としないと使うことができない。
  dom.byId("target_dom_id").appendChild(myButton.domNode); 
});

requireの第二引数の並び順は、第一引数の並び順に対応します。requireしたモジュールは、第二引数の関数内でのみ有効(利用可能)な事がわかると思います。なまらモダンですね!

あと、requireするときのモジュールの表し方の違いにも注目。レガシーはドット(.)区切り、モダンはスラッシュ(/)区切りです。

3-3:ajaxでのアクセス

どうすると思いますか?…はい正解です、ajaxするモジュールをrequireの第一引数で読み込み、第二引数の関数内で読み込んだ関数を実行させます。読み込むモジュール名と、関数さえわかれば簡単に実行できますよね。モジュールはdojo/request、関数はgetになります(リクエストメソッドがgetの場合です。ではpostの場合は?そうです、postです)

require(
            [
                "dojo/request"
            ],
            function(request) {
                 request.get("./data.json", {handleAs:"json"})
                        .then(function(data){
                              //リクエスト成功時。
                              //取得したデータはdataで参照できる。
                         });
            });

みたとおりですね。getの第一引数が、アクセスするURIになります。第二引数はajaxアクセスする際のパラメータで、ここではhandleAsで結果をどのように解釈するかを指定しています。次の.thenでは、リクエスト結果をハンドリングします。

ここでは引数として関数を一つ指定しています。一つ目はリクエスト成功時の処理です。先ほどhandleAsでjsonを指定していますので、ここでの関数の引数dataはjson形式として扱うことができます。

4:まとめ

雰囲気は伝わったでしょうか? このあたりを参考にしています。次回は、今回の続きで、ajaxしたものをダイアログに表示するところについて書きます。

Twitter プロフィール
コメントなどあったら、お気軽に♪
カテゴリ別アーカイブ
タグクラウド
QRコード
QRコード