AngularJS:factory $ http.get JSON文件

我正在寻找与硬编码的JSON文件本地开发。 我的JSON文件如下(放入JSONvalidation器时有效):

{ "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代码replace了JSON,它不起作用。 我已经看到$ http和$资源的许多不同的例子,但不知道去哪里。 我正在寻找最简单的解决scheme。 我只是想拉数据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)如果您没有运行任何types的networking服务器,只需要使用file://index.html进行testing,那么您可能会遇到同源策略问题。 看到:

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

许多浏览器不允许本地托pipe的文件访问其他本地托pipe的文件。 Firefox确实允许,但前提是你正在加载的文件与html文件(或子文件夹)包含在同一个文件夹中。

2)从$ http.get()返回的成功函数已经为你分割结果对象:

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

所以用函数(response)调用成功是多余的,并返回response.data。

3)成功函数不返回你传递函数的结果,所以这不符合你的想法:

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

然后你可以在控制器的计算中asynchronous使用这个值:

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

我想指出, 接受答案第四部分是错误的

 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 ),这是因为我们正在进行asynchronous调用。

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


在Angular中,当你想进行asynchronous调用时,使用$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的原因是我刚刚从文档中发现,这两个方法已被弃用。

$http传统promise方法的成功和错误已被弃用。 改为使用标准then方法。

这个答案帮了我很大的忙,并指出了正确的方向,但是对我和其他人有用的是:

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

我大概有这些问题。 我需要从Visual Studio 2013中debuggingAngularJs应用程序。

默认情况下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>

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

++这为我工作。 这是vanilla javascirpt和良好的用例如使用ngMocks库进行testing时的混乱:

 <!-- 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> 

这是包含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" }; 

最后,在代码中的任何地方使用JSON数据

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

注意: –这对于testing是很好的,甚至karma.conf.js接受这些文件来运行testing,如下所示。 此外,我build议这只是为了消除数据和testing/development环境。

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

希望这可以帮助。

++build立在此回答的顶部https://stackoverflow.com/a/24378510/4742733

UPDATE

一个简单的方法,对我来说只是在代码的底部包含一个返回任何JSONfunction

 // 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.comhttp://img.dovov.comM/MV5BMjEzNDUxMDI4OV5BMl5BanBnXkFtZTcwMjE2MzczNQ@@._V1_SX300.jpg", "Metascore": "N/A", "imdbRating": "8.2", "imdbVotes": "5", "imdbID": "tt1937109", "Type": "movie", "Response": "True" } }