Json; JSON with Connection Manager

先の例では、YUIのConnection ManagerとXMLを使って、XHR(XMLHttpRequest)のサンプリングを行った。
RESTでマッシュアップをする(より広義には、Ajaxを実装する)際に、XMLだけでなく、JSONを外すわけにはいかない。(JSONについては、Wikipwdia:JSONを参照のこと)

YAMLから派生した、ハッシュ(辞書)形式のJSONは、Javascriptとの相性の良さから、UIとサーバープログラムとの分離といった、アプリケーション・アーキテクチャを考える上でも重要である。

YUIにあるJSONをパースするモジュールのテストを行う。

サンプリングは、YUIのExampleをベースにした。YUIのExampleは、(Exampleのサーバー上にある)PHPプログラムの呼び出しを行っている。
開発機にあるApacheからレスポンスされるサンプルについては、クロスサイトスクリプティングを防止するという意味で、same oringin policy(スクリプトがアクセスできるサーバーは、それをレスポンスしたサーバーのみである)が適用されるために、このPHPプログラムを、サンプルのJavascriptから呼ぶことはできない。
先の(天気予報の)例のように、一度、サーバープログラムをProxyとして使う所以は、ここにある。

YUIのExampleには、幸い、以下のようなデータが示されているので、それを(サンプルのhtmlがあるディレクトリにdataディレクトリを作り)、ajax_json.txt(エンコーディングUTF-8)として保存して、これを取得してみた。

[
{ "animal" : "Cat", "message" : "Meow" },
{ "animal" : "Dog", "message" : "Woof" },
{ "animal" : "Cow", "message" : "Moo" },
{ "animal" : "Duck", "message" : "Quack" },
{ "animal" : "Lion", "message" : "Roar" }
]

初期の画面は、以下。

ここで、「メッセージの取得」ボタンを押すと、このajax_json.txtを(XHRで)取得して、以下の画面を表示する。

以下に、Javascriptを含む、htmlの全文を示す。javascript内でevalをしないというのも、YUIに共通した(セキュリティー上重要な)特徴である。

<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<META http-equiv="Content-Style-Type" content="text/css">
<TITLE>Ajax_Sampling</TITLE>
<style type="text/css">
body {
	margin:0;
	padding:0;
}

#demo {
	width: 200px;
	hight: auto;
	padding: 10px;
    background-color: #6D739A;
    color: white;
	border: 1px solid green;
	
}
/*処理待ち画像*/
#wait {
    width: 18px;
    height: 18px;
}
</style>

<!-- 読み込むjs --> 
<script type="text/javascript" src="scripts/yui/yahoo/yahoo-min.js" >
</script> 
<script type="text/javascript" src="scripts/yui/yahoo-dom-event/yahoo-dom-event.js" >
</script> 
<script type="text/javascript" src="scripts/yui/connection/connection-min.js" >
</script> 
<script type="text/javascript" src="scripts/yui/json/json-min.js" >
</script> 

<script type="text/javascript">
// namespaceの定義
YAHOO.namespace('EGP');

var ajaxHandlers=YAHOO.EGP.ajaxHandlers;
var ajaxCallback=YAHOO.EGP.ajaxCallback;
var btnHandlers=YAHOO.EGP.btnHandlers;

// bottunクリックに処理を仕掛ける。
YAHOO.util.Event.on('demo_btn','click',function (e) {
    // demo_msgのdivにAliasをつける。見通しが悪い感じがしないかな。
    var msg_section = YAHOO.util.Dom.get('demo_msg');
    msg_section.innerHTML = '';

    // Define the callbacks for the asyncRequest
    var callbacks = {

        success : function (o) {
			YAHOO.util.Dom.get('wait').innerHTML='';

            var messages = [];
            try {
                // Jsonデータをパースする。パースできないとexceptionがでる。
                // (注※)
				// [
				//    { "animal" : "Cat",  "message" : "Meow"  },
				//    { "animal" : "Dog",  "message" : "Woof"  },
				//    { "animal" : "Cow",  "message" : "Moo"   },
				//    { "animal" : "Duck", "message" : "Quack" },
				//    { "animal" : "Lion", "message" : "Roar"  }
				// ]
				// は、プロパティー:animal, messageを持つオブジェクトの配列
				// に変換される。evalは不要。
                messages = YAHOO.lang.JSON.parse(o.responseText);
            }
            catch (x) {
                alert("JSON Parse failed!");
                return;
            }

            // The returned data was parsed into an array of objects.
            // Add a P element for each received message
            // (注※)に示したオブジェクト配列より、htmlを形成する。
            
            for (var i = 0, len = messages.length; i < len; ++i) {
				// オブジェクトの取得
            	var m = messages[i];
				// pタグで段落を作る。
                var p = document.createElement('p');
				// オブジェクト.プロパティーで情報を取得し、TextNodeを形成する。
				var message_text = document.createTextNode(
                        m.animal + ' says "' + m.message + '"');
                // 上で形成したTextNodeを、その上で作った段落(pタグ)につける。
                p.appendChild(message_text);
                // msg_sectionは、demo_msgのAlias
                msg_section.appendChild(p);
            }
        },

        failure : function (o) {
			YAHOO.util.Dom.get('wait').innerHTML='';
            // HXRプロセスが生きているかどうか確かめる。
            if (!YAHOO.util.Connect.isCallInProgress(o)) {
                alert("Async call failed!");
            }
        },

        // 5秒待って帰ってこなかったら、Timeoutし、callbacks.failureへいく。
        timeout : 5000
    }

    // JSONデータをレスポンスするPHPプログラムを呼ぶ。
    YAHOO.util.Connect.asyncRequest('GET',
    	    "data/ajax_json.txt", callbacks);
	// wait画像(処理待ち画像)の表示
	YAHOO.util.Dom.get('wait').innerHTML=
				"<img src='./images/wait.gif'/>";

});

</script>
</HEAD>
<BODY>
<div id="demo">
	<!-- 処理待ち画像 -->
	<div id='wait'></div>
    <input type="button" id="demo_btn" value="メッセージの取得">
    <div id="demo_msg"></div>
</div>
</BODY>
</HTML>