84

我希望仅使用硬编码的 JSON 文件在本地进行开发。我的 JSON 文件如下(放入 JSON 验证器时有效):

{
    "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 工作了。但是,既然我已经用 $http.get 代码替换了 JSON,它就不起作用了。我已经看到了很多 $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
});

任何和所有的帮助表示赞赏。谢谢!

4

5 回答 5

218

Okay, here's a list of things to look into:

1) If you're not running a webserver of any kind and just testing with file://index.html, then you're probably running into same-origin policy issues. See:

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

Many browsers don't allow locally hosted files to access other locally hosted files. Firefox does allow it, but only if the file you're loading is contained in the same folder as the html file (or a subfolder).

2) The success function returned from $http.get() already splits up the result object for you:

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

So it's redundant to call success with function(response) and return response.data.

3) The success function does not return the result of the function you pass it, so this does not do what you think it does:

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

This is closer to what you intended:

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

4) But what you really want to do is return a reference to an object with a property that will be populated when the data loads, so something like this:

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 will start off null, and when the data loads, it will point at it.

Alternatively you can return the actual promise the $http.get returns and use that:

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

And then you can use the value asynchronously in calculations in a controller:

$scope.foo = "Hello World";
mainInfo.success(function(data) { 
    $scope.foo = "Hello "+data.contentItem[0].username;
});
于 2013-06-05T04:33:45.290 回答
21

我想指出Accepted Answer 的第四部分是错误的

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;    
});

@Karl Zilles 编写的上述代码将失败,因为obj它总是在接收数据之前返回(因此值将始终为null),这是因为我们正在进行异步调用。

类似问题的细节在这篇文章中讨论


在 Angular 中,$promise当您想要进行异步调用时,使用它来处理获取的数据。

最简单的版本是

theApp.factory('mainInfo', function($http) { 
    return {
        get:  function(){
            $http.get('content.json'); // this will return a promise to controller
        }
});


// and in controller

mainInfo.get().then(function(response) { 
    $scope.foo = response.data.contentItem;
});

我不使用的原因successerror我刚刚从文档中发现,这两种方法已被弃用。

旧的$httppromise 方法成功和错误已被弃用。请改用标准then方法。

于 2015-08-06T01:53:46.083 回答
4

这个答案对我有很大帮助,并为我指明了正确的方向,但对我和希望其他人有用的是:

menuApp.controller("dynamicMenuController", function($scope, $http) {
$scope.appetizers= [];
$http.get('config/menu.json').success(function(data) { 
    console.log("success!");
    $scope.appetizers = data.appetizers;
        console.log(data.appetizers);
    });    
});
于 2014-07-22T01:37:03.810 回答
1

我大约有这些问题。我需要从 Visual Studio 2013 调试 AngularJs 应用程序。

默认情况下,IIS Express 限制对本地文件(如 json)的访问。

但是,首先:JSON 具有 JavaScript 语法。

第二:允许使用javascript文件。

所以:

  1. 将 JSON 重命名为 JS ( data.json->data.js)。

  2. 正确的加载命令($http.get('App/data.js').success(function (data) {...

  3. 将脚本 data.js 加载到页面 ( <script src="App/data.js"></script>)

接下来以通常的方式使用加载的数据。当然,这只是解决方法。

于 2015-06-23T19:41:00.373 回答
1

++这对我有用。在使用库进行测试时,它vanilla javascirpt适用于诸如整理杂乱的用例:ngMocks

<!-- specRunner.html - keep this at the top of your <script> asset loading so that it is available readily -->
<!--  Frienly tip - have all JSON files in a json-data folder for keeping things organized-->
<script src="json-data/findByIdResults.js" charset="utf-8"></script>
<script src="json-data/movieResults.js" charset="utf-8"></script>

这是javascript包含JSON数据的文件

// json-data/JSONFindByIdResults.js
var JSONFindByIdResults = {
     "Title": "Star Wars",
     "Year": "1983",
     "Rated": "N/A",
     "Released": "01 May 1983",
     "Runtime": "N/A",
     "Genre": "Action, Adventure, Sci-Fi",
     "Director": "N/A",
     "Writer": "N/A",
     "Actors": "Harrison Ford, Alec Guinness, Mark Hamill, James Earl Jones",
     "Plot": "N/A",
     "Language": "English",
     "Country": "USA",
     "Awards": "N/A",
     "Poster": "N/A",
     "Metascore": "N/A",
     "imdbRating": "7.9",
     "imdbVotes": "342",
     "imdbID": "tt0251413",
     "Type": "game",
     "Response": "True"
};

最后,在代码中的任何位置使用 JSON 数据

// working with JSON data in code
var findByIdResults = window.JSONFindByIdResults;

注意:-这非常适合测试,甚至karma.conf.js可以接受这些文件来运行测试,如下所示。此外,我建议仅将其用于整理数据和testing/development环境。

// extract from karma.conf.js
files: [
     'json-data/JSONSearchResultHardcodedData.js',
     'json-data/JSONFindByIdResults.js'
     ...
]

希望这可以帮助。

++建立在这个答案之上https://stackoverflow.com/a/24378510/4742733

更新

对我有用的一种更简单的方法是function在代码底部包含一个返回任何内容JSON

// within test code
let movies = getMovieSearchJSON();
.....
...
...
....
// way down below in the code
function getMovieSearchJSON() {
      return {
         "Title": "Bri Squared",
         "Year": "2011",
         "Rated": "N/A",
         "Released": "N/A",
         "Runtime": "N/A",
         "Genre": "Comedy",
         "Director": "Joy Gohring",
         "Writer": "Briana Lane",
         "Actors": "Brianne Davis, Briana Lane, Jorge Garcia, Gabriel Tigerman",
         "Plot": "N/A",
         "Language": "English",
         "Country": "USA",
         "Awards": "N/A",
         "Poster": "http://ia.media-imdb.com/images/M/MV5BMjEzNDUxMDI4OV5BMl5BanBnXkFtZTcwMjE2MzczNQ@@._V1_SX300.jpg",
         "Metascore": "N/A",
         "imdbRating": "8.2",
         "imdbVotes": "5",
         "imdbID": "tt1937109",
         "Type": "movie",
         "Response": "True"
   }
}
于 2016-04-05T10:39:43.263 回答