Я ищу локальную разработку, используя только жестко закодированный файл 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" }
]
}
]
}
Я получил свой контроллер, фабрику и html, когда JSON был жестко закодирован внутри фабрики. Однако теперь, когда я заменил 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) Если вы не используете какой-либо веб-сервер и просто тестируете его с помощью file: //index.html, то вы, вероятно, столкнетесь с проблемами политики одного и того же происхождения. Видеть:
https://code.google.com/archive/p/browsersec/wikis/Part2.wiki#Same-origin_policy
Многие браузеры не разрешают локально размещенным файлам доступ к другим локально размещенным файлам. Firefox допускает это, но только в том случае, если загружаемый файл находится в той же папке, что и файл html (или подпапка).
2) Функция успеха, возвращаемая из $ http.get (), уже разделяет за вас объект результата:
$http({method: 'GET', url: '/someUrl'}).success(function(data, status, headers, config) {
Поэтому излишне вызывать успех с помощью функции (ответа) и возвращать 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 будет начинаться с нуля, и при загрузке данных он будет указывать на него.
В качестве альтернативы вы можете вернуть фактическое обещание, которое возвращает $ 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; });
источник
Хочу отметить, что четвертая часть принятого ответа неверна .
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; });
Причина, по которой я не использую,
success
иerror
я только что узнал из документа , эти два метода устарели.источник
return $http.get('content.json');
на заводе, иначе возврат будет нулевым..success
теперь устарела..then
Вместо этого используйте . docs.angularjs.org/api/ng/service/$httpэтот ответ мне очень помог и указал мне в правильном направлении, но то, что сработало для меня и, надеюсь, других, так это:
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); }); });
источник
У меня примерно эти проблемы. Мне нужно отладить приложение AngularJs из Visual Studio 2013.
По умолчанию IIS Express ограничивает доступ к локальным файлам (например, json).
Но сначала: JSON имеет синтаксис JavaScript.
Второе: файлы javascript разрешены.
Так:
переименуйте JSON в JS (
data.json->data.js
).правильная команда загрузки (
$http.get('App/data.js').success(function (data) {...
загрузить скрипт data.js в page (
<script src="App/data.js"></script>
)Затем используйте загруженные данные обычным образом. Конечно, это просто обходной путь.
источник
++ Это сработало для меня. Это
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" } }
источник