AngularJS:工厂 $http.get JSON 文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16930473/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
AngularJS: factory $http.get JSON file
提问by jstacks
I am looking to develop locally with just a hardcoded JSON file. My JSON file is as follows (valid when put into JSON validator):
我希望仅使用硬编码的 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" }
]
}
]
}
I've gotten my controller, factory, and html working when the JSON was hardcoded inside the factory. However, now that I've replaced the JSON with the $http.get code, it doesn't work. I've seen so many different examples of both $http and $resource but not sure where to go. I'm looking for the simplest solution. I'm just trying to pull data for ng-repeat and similar directives.
当 JSON 在工厂内部进行硬编码时,我的控制器、工厂和 html 就可以正常工作了。但是,现在我已经用 $http.get 代码替换了 JSON,它不起作用。我见过很多不同的 $http 和 $resource 示例,但不知道该去哪里。我正在寻找最简单的解决方案。我只是想为 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!
任何和所有的帮助表示赞赏。谢谢!
回答by Karen Zilles
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:
1) 如果您没有运行任何类型的网络服务器,而只是使用 file://index.html 进行测试,那么您可能会遇到同源策略问题。看:
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.
所以用 function(response) 调用成功并返回 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;
});
回答by Qiang
I wanted to note that the fourth part of Accepted Answer is wrong.
我想指出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;
});
The above code as @Karl Zilles wrote will fail because objwill 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 $promiseto 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 successand erroris I just found out from the doc, these two methods are deprecated.
我不使用的原因success和error是我刚刚从发现的文档,这两种方法已被弃用。
The
$httplegacy promise methods success and error have been deprecated. Use the standardthenmethod instead.
该
$http遗产的承诺方法成功和错误已被弃用。请改用标准then方法。
回答by jp093121
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);
});
});
回答by Alex Sam
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:
所以:
rename JSON to JS (
data.json->data.js).correct load command (
$http.get('App/data.js').success(function (data) {...load script data.js to page (
<script src="App/data.js"></script>)
将 JSON 重命名为 JS (
data.json->data.js)。正确的加载命令(
$http.get('App/data.js').success(function (data) {...将脚本 data.js 加载到页面 (
<script src="App/data.js"></script>)
Next use loaded data an usual manner. It is just workaround, of course.
接下来以通常的方式使用加载的数据。当然,这只是解决方法。
回答by Akash
++This worked for me. It's vanilla javascirptand good for use cases such as de-cluttering when testing with ngMockslibrary:
++这对我有用。它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 javascriptfile that contains the JSONdata
这是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"
};
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.jsaccepts these files for running tests as seen below. Also, I recommend this only for de-cluttering data and testing/developmentenvironment.
注意:-这非常适合测试,甚至karma.conf.js可以接受这些文件来运行测试,如下所示。此外,我建议仅将其用于整理数据和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
更新
An easier way that worked for me is just include a functionat 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"
}
}

