うごく生ゴミプログラマの備忘録

うごく生ゴミ 〜再臨〜

JavaScript(Backbone.js)で、jsonファイルの読み込み方メモ

アプリケーションの設定値を定義した json ファイルの設定値を Backbone.Model を継承したオブジェクトで保持するようにしたら、 jQueryajax をそのまま使うよりすっきり出来た気がする(個人の感想)のでメモっとく。

もっと良いやり方あったらおしえてください。

まず html 側。 大事なのは head タグ内の script タグ部分。 Backbone.js には jQuery と underscore が必要なので、それらのライブラリを読み込んでいます。

stylesheet 読み込み部分はどうでもいいです。

<!DOCTYPE html>
<html lang="ja">
    <head>
       <meta charset="utf-8">
       <meta http-equiv="Pragma" content="no-cache">
       <meta http-equiv="Cache-Control" content="no-cache">
       <title>title</title>
       <link rel='stylesheet' href='./css/style.css'/>

       <!-- 各ライブラリの読み込み -->
       <script src="./script/lib/jquery-2.1.4.min.js"></script>
       <script src="./script/lib/underscore-min.js"></script>
       <script src="./script/lib/backbone-min.js"></script>

       <!-- 今回書くJavaScriptファイル -->
       <script src="./script/app.js"></script>
   </head>
    <body>
        <p>sample</p>
    </body>
</html>

で、次、読み込み対象の .json ファイルについて 今回は2つ .json ファイルを読み込むことにする。

一つ目の .json ファイル アプリケーションの名前とバージョンを持っている設定ファイルの想定。

config1.json

{
    "app_name": "アプリケーション名",

    "version": "1.00"
}

二つ目 画面か警告とかエラーとかの文言を定義している設定ファイルの想定。

config2.json

{
    "MESSAGE_001": "メッセージゼロゼロイチ",

    "MESSAGE_002": "メッセージゼロゼロニ"
}

で、最後に実際に、上記の json ファイルを読み込んでいるJavaScriptファイルについて。

app.js

var app = app || {};

// config.jsonを読み込むオブジェクト
app.Config1 = Backbone.Model.extend({

    // .json ファイルのパスを設定
    url: './config1.json',
});


app.Config2 = Backbone.Model.extend({

    // .json ファイルのパスを設定
    url: './config2.json',
});


(function(){
    'use strict';
    var config1 = new app.Config1();
    var config2 = new app.Config2();

    config1.fetch().then( function() {

        app.config1 = config1;

        return config2.fetch();

    }).then( function () {
    
        app.config2 = config2; 

        console.log( app.config1.get('app_name') );
        console.log( app.config1.get('version') );
        
        console.log( app.config2.get('MESSAGE_001') );
        console.log( app.config2.get('MESSAGE_002') );
    });

}());

ちょっと長くなってしまった。 まず、前半部分

var app = app || {};

// config.jsonを読み込むオブジェクト
app.Config1 = Backbone.Model.extend({

    // .json ファイルのパスを設定
    url: './config1.json',
});


app.Config2 = Backbone.Model.extend({

    // .json ファイルのパスを設定
    url: './config2.json',
});

jsonを読み込むためのクラスを Backbone.Model を継承して定義しています。 Backbone.Model は url 属性に定義したリソースを取得、作成、更新、削除を行う機能を持っているのでそれを使って楽します。 なので、クラスの定義は url 属性を定義するだけでおしまい。

次、後半部分

(function(){
    'use strict';
    var config1 = new app.Config1();
    var config2 = new app.Config2();

    config1.fetch().then( function() {

        app.config1 = config1;

        return config2.fetch();

    }).then( function () {
    
        app.config2 = config2; 

        console.log( app.config1.get('app_name') );
        console.log( app.config1.get('version') );

        console.log( app.config2.get('MESSAGE_001') );
        console.log( app.config2.get('MESSAGE_002') );
    });

}());

まず、前半部分で定義したクラスを new して変数に代入します。

それで、ここからが個人的にややこしいと感じた部分。

config1.fetch() は実際には 前半部分のクラスの定義設定した url に対して HTTPリクエストのGETメソッドで非同期で取得しにいっている。 で、非同期ってことは

config1.fetch();
console.log( config1.get('app_name') );
console.log( config1.get('version') );
        

こんな風に書くと、config1.fetch(); でjsonファイルを読み込みに行ってるんだけど、読み込み終わらないうちに、2行目の処理に進んじゃんって、 コンソールには undefined undefined って出力される可能性が高い。

で、それを防ぐためにどうしたかって言うと、 .fetch() で jQuery のDifferedオブジェクトが返ってくるので、Differedオブジェクトの then()メソッドを使用して、fetch(実際には HTTP の GETメソッド )が終了するのを待って、次の処理に移るようにしています。

今回の場合 config1.json の読み込みが正常に終わったらば、次は config2.json の読み込みをして、 それもちゃんと終わったらば、確認のために、それぞれの読み込んだ値をコンソールに表示するようにしています。

console.log( app.config1.get('app_name') );
console.log( app.config1.get('version') );

console.log( app.config2.get('MESSAGE_001') );
console.log( app.config2.get('MESSAGE_002') );