简体   繁体   English

AngularJS:工厂$ http.get JSON文件

[英]AngularJS: factory $http.get JSON file

I am looking to develop locally with just a hardcoded JSON file. 我期待在本地开发只有一个硬编码的JSON文件。 My JSON file is as follows (valid when put into JSON validator): 我的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" }
            ]
        }
    ]
}

I've gotten my controller, factory, and html working when the JSON was hardcoded inside the factory. 当JSON在工厂内硬编码时,我已经得到了我的控制器,工厂和html工作。 However, now that I've replaced the JSON with the $http.get code, it doesn't work. 但是,现在我已经用$ http.get代码替换了JSON,它不起作用。 I've seen so many different examples of both $http and $resource but not sure where to go. 我已经看到了很多不同的$ http和$资源的例子,但不知道该去哪里。 I'm looking for the simplest solution. 我正在寻找最简单的解决方案。 I'm just trying to pull data for ng-repeat and similar directives. 我只是想为ng-repeat和类似的指令提取数据。

Factory: 厂:

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

Any and all help is appreciated. 任何和所有的帮助表示赞赏。 Thanks! 谢谢!

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. 1)如果您没有运行任何类型的网络服务器并且仅使用file://index.html进行测试,那么您可能会遇到同源策略问题。 See: 看到:

https://code.google.com/archive/p/browsersec/wikis/Part2.wiki#Same-origin_policy 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). Firefox确实允许它,但前提是您加载的文件包含在与html文件(或子文件夹)相同的文件夹中。

2) The success function returned from $http.get() already splits up the result object for you: 2)$ http.get()返回的成功函数已经为你分割了结果对象:

$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. 因此,使用函数(响应)调用成功并返回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: 3)成功函数不会返回您传递的函数的结果,因此这不符合您的想法:

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: 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 will start off null, and when the data loads, it will point at it. mainInfo.content将从null开始,当数据加载时,它将指向它。

Alternatively you can return the actual promise the $http.get returns and use that: 或者,您可以返回$ http.get返回的实际承诺并使用:

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

I wanted to note that the fourth part of Accepted Answer is wrong . 我想说明接受答案第四部分是错误的

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

The above code as @Karl Zilles wrote will fail because obj will always be returned before it receives data (thus the value will always be null ) and this is because we are making an Asynchronous call. 上面的代码@Karl Zilles写的将失败,因为obj将始终在接收数据之前返回(因此值将始终为null ),这是因为我们正在进行异步调用。

The details of similar questions are discussed in this post 本文将讨论类似问题的详细信息


In Angular, use $promise to deal with the fetched data when you want to make an asynchronous call. 在Angular中,当您想要进行异步调用时,使用$promise处理获取的数据。

The simplest version is 最简单的版本是

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

The reason I don't use success and error is I just found out from the doc , these two methods are deprecated. 我不使用successerror的原因是我刚刚从doc中发现,这两种方法都被弃用了。

The $http legacy promise methods success and error have been deprecated. $http遗留承诺方法成功和错误已被弃用。 Use the standard then method instead. 使用标准then方法来代替。

this answer helped me out a lot and pointed me in the right direction but what worked for me, and hopefully others, is: 这个答案帮助了我很多,并指出了我正确的方向,但对我有用的,希望其他人,是:

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

I have approximately these problem. 我有大约这些问题。 I need debug AngularJs application from Visual Studio 2013. 我需要从Visual Studio 2013调试AngularJs应用程序。

By default IIS Express restricted access to local files (like json). 默认情况下,IIS Express限制访问本地文件(如json)。

But, first: JSON have JavaScript syntax. 但是,首先:JSON具有JavaScript语法。

Second: javascript files is allowed. 第二:允许使用javascript文件。

So: 所以:

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

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

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

Next use loaded data an usual manner. 接下来以常规方式使用加载数据。 It is just workaround, of course. 当然,这只是解决方法。

++ This worked for me. ++这对我有用。 It's vanilla javascirpt and good for use cases such as de-cluttering when testing with ngMocks library: 它是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>

This is your javascript file that contains the JSON data 这是包含JSON数据的javascript文件

// 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"
};

Finally, work with the JSON data anywhere in your code 最后,在代码中的任何位置使用JSON数据

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

Note:- This is great for testing and even karma.conf.js accepts these files for running tests as seen below. 注意: -这非常适合测试,甚至karma.conf.js接受这些文件来运行测试,如下所示。 Also, I recommend this only for de-cluttering data and testing/development environment. 此外,我建议仅用于解决数据和testing/development环境。

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

Hope this helps. 希望这可以帮助。

++ Built on top of this answer https://stackoverflow.com/a/24378510/4742733 ++建立在这个答案之上https://stackoverflow.com/a/24378510/4742733

UPDATE UPDATE

An easier way that worked for me is just include a function at the bottom of the code returning whatever JSON . 对我来说更简单的方法就是在代码底部包含一个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"
   }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM