JavaScript(Backbone.js)で、jsonファイルの読み込み方メモ
アプリケーションの設定値を定義した json ファイルの設定値を Backbone.Model を継承したオブジェクトで保持するようにしたら、 jQuery の ajax をそのまま使うよりすっきり出来た気がする(個人の感想)のでメモっとく。
もっと良いやり方あったらおしえてください。
まず 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') );