1. ホーム
  2. json

[解決済み] AngularJS: ファクトリー $http.get JSON ファイル

2023-06-08 02:49:54

質問

ハードコードされたJSONファイルだけを使ってローカルに開発したいと考えています。私のJSONファイルは以下の通りです(JSON Validatorにかけると有効です)。

{
    "contentItem": [
            {
            "contentID" : "1", 
            "contentVideo" : "file.mov",
            "contentThumbnail" : "url.jpg",
            "contentRating" : "5",
            "contentTitle" : "Guitar Lessons",
            "username" : "Username", 
            "realname" : "Real name",
            "contentTags" : [
                { "tag" : "Guitar"},
                { "tag" : "Intermediate"},
                { "tag" : "Chords"}
            ],      
            "contentAbout" : "Learn how to play guitar!",
            "contentTime" : [
                { "" : "", "" : "", "" : "", "" : ""},
                { "" : "", "" : "", "" : "", "" : ""}
            ],          
            "series" :[
                { "seriesVideo" : "file.mov", "seriesThumbnail" : "url.jpg", "seriesTime" : "time", "seriesNumber" : "1", "seriesTitle" : "How to Play Guitar" },
                { "videoFile" : "file.mov", "seriesThumbnail" : "url.jpg", "seriesTime" : "time", "seriesNumber" : "2", "seriesTitle" : "How to Play Guitar" }
            ]
        },{
            "contentID" : "2", 
            "contentVideo" : "file.mov",
            "contentThumbnail" : "url.jpg",
            "contentRating" : "5",
            "contentTitle" : "Guitar Lessons",
            "username" : "Username", 
            "realname" : "Real name",
            "contentTags" : [
                { "tag" : "Guitar"},
                { "tag" : "Intermediate"},
                { "tag" : "Chords"}
            ],      
            "contentAbout" : "Learn how to play guitar!",
            "contentTime" : [
                { "" : "", "" : "", "" : "", "" : ""},
                { "" : "", "" : "", "" : "", "" : ""}
            ],          
            "series" :[
                { "seriesVideo" : "file.mov", "seriesThumbnail" : "url.jpg", "seriesTime" : "time", "seriesNumber" : "1", "seriesTitle" : "How to Play Guitar" },
                { "videoFile" : "file.mov", "seriesThumbnail" : "url.jpg", "seriesTime" : "time", "seriesNumber" : "2", "seriesTitle" : "How to Play Guitar" }
            ]
        }
    ]
}

JSONがファクトリー内にハードコードされていたときは、コントローラ、ファクトリー、htmlが動作していました。しかし、JSONを$http.getのコードに置き換えたところ、うまくいかなくなりました。私は、$httpと$resourceの両方の非常に多くの異なる例を見てきましたが、どこに行けばいいのかわかりません。最もシンプルな解決策を探しています。私はちょうどng-repeatと同様のディレクティブのためのデータを引き出そうとしています。

ファクトリーです。

theApp.factory('mainInfoFactory', function($http) { 
    var mainInfo = $http.get('content.json').success(function(response) {
        return response.data;
    });
    var factory = {}; // define factory object
    factory.getMainInfo = function() { // define method on factory object
        return mainInfo; // returning data that was pulled in $http call
    };
    return factory; // returning factory to make it ready to be pulled by the controller
});

どんなことでも、ご協力をお願いします。ありがとうございます。

どのように解決するのですか?

さて、ここで調べたいことを列挙します。

1) Web サーバーを使用しておらず、単に file://index.html でテストしている場合、おそらく同一生成元ポリシーの問題に遭遇していると思われます。 参照してください。

https://code.google.com/archive/p/browsersec/wikis/Part2.wiki#Same-origin_policy

多くのブラウザは、ローカルにホストされたファイルが他のローカルにホストされたファイルにアクセスすることを許可していません。 Firefox はそれを許可しますが、読み込むファイルが html ファイルと同じフォルダー (またはサブフォルダー) に含まれている場合のみです。

2) $http.get() から返される success 関数は、すでにあなたのために結果オブジェクトを分割しています。

$http({method: 'GET', url: '/someUrl'}).success(function(data, status, headers, config) {

なので、function(response)でsuccessを呼び出してresponse.dataを返すのは冗長です。

3) success関数は渡した関数の結果を返さないので、これはあなたが考えているようなことはしません。

var mainInfo = $http.get('content.json').success(function(response) {
        return response.data;
    });

この方が意図したものに近いです。

var mainInfo = null;
$http.get('content.json').success(function(data) {
    mainInfo = data;
});

4) しかし、本当にやりたいことは、データがロードされるときに入力されるプロパティを持つオブジェクトへの参照を返すことなので、次のようなものです。

theApp.factory('mainInfo', function($http) { 

    var obj = {content:null};

    $http.get('content.json').success(function(data) {
        // you can do some processing here
        obj.content = data;
    });    

    return obj;    
});

mainInfo.contentは最初はNULLで、データがロードされるとそれを指すようになります。

代わりに、$http.getが返す実際のプロミスを返すことができ、それを使用することができます。

theApp.factory('mainInfo', function($http) { 
    return $http.get('content.json');
});

そして、その値をコントローラ内の計算で非同期に使用することができます。

$scope.foo = "Hello World";
mainInfo.success(function(data) { 
    $scope.foo = "Hello "+data.contentItem[0].username;
});