2013-06-05 3 views
79

Я ищу для разработки локально только с жестко закодированным файлом 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

Не работает? Что оно делает? Вызывает ли ошибка? Есть ли выход в консоли JavaScript? –

+0

Консоль просто говорит «Не удалось загрузить ресурс», а затем имеет путь к файлу console.json. По какой-то причине это не погрузка. Моя фабрика и JSON точно так же, как вы видите выше. Когда я жестко программирую JSON на заводе, он работает. – jstacks

+0

Что вы используете в качестве бэкэнд? NodeJs или простой сервер на базе python или что-то еще? – callmekatootie

ответ

214

Хорошо, вот список вещей, чтобы искать в:

1) Если вы не используете веб-сервер любого рода и только тестирование с файлом: //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; 
}); 
+26

Эй, это ответ И угловой $ http-курс по той же цене - Хороший ответ! – Mat

+4

В вашем объяснении в разделе 4), не будет ли вызов «return obj» вызван до разрешения $ http.get()? Просто спрашиваю, потому что я думаю, что это то, что происходит со мной. – Pathsofdesign

+3

Да, будет. Но замыкание, вызванное при разрешении $ http.get(), сохраняет ссылку на «obj». Он заполнит свойство содержимого, которое вы затем сможете использовать. –

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

Разве вы не должны делать что-то подобное внутри службы? – Katana24

+0

Никогда не делайте этого в контроллере! Плохо! Вы должны написать это как услугу. Хотя способ, которым вы назвали значение json, не является неправильным, вы должны иметь сервис, возвращающий обещание, не выполняющее этого в контроллере. С точки зрения повторного использования это ужасно. Например, вы выполняете и $ http.get() каждый раз, когда вы загружаете контроллер, и получаете кешированную версию вызова в службе. – Downpour046

1

У меня есть примерно такая проблема. Мне нужно отлаживать приложение AngularJs от Visual Studio 2013.

По умолчанию 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>)

Следующая использование загруженных данных обычным способом. Это просто временное решение, конечно.

18

Я хотел бы отметить, что Четвертая часть принятого ответа неверна .

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), и это происходит потому, что мы делаем в асинхронного вызова.

Деталь подобных вопросов обсуждается в this post


В Угловом, используйте $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 это я только что узнал от doc, эти два метода являются устаревшими.

$http Удовлетворительные методы успеха и ошибки устарели. Вместо этого используйте стандартный метод then.

+2

Используйте '' return $ http.get ('content.json'); '' на фабрике, иначе возврат равно null. – Francesco

+1

Эй, просто хедз-ап. Причина, по которой он работает (вопреки вашему ответу здесь), заключается в том, что вы возвращаете ссылку на объект. Функция успеха также имеет ссылку на тот же объект. Когда функция ajax в конечном итоге возвращает, она обновляет свойство «content» в исходном объекте, который был возвращен. Попробуй. :-) –

+1

P.s. '.success' теперь устарел. Вместо этого используйте '. Then'. https://docs.angularjs.org/api/ng/service/$http – redfox05

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

UPDATE

более простой способ, который работал для меня просто включить 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/[email protected]@._V1_SX300.jpg", 
     "Metascore": "N/A", 
     "imdbRating": "8.2", 
     "imdbVotes": "5", 
     "imdbID": "tt1937109", 
     "Type": "movie", 
     "Response": "True" 
    } 
} 
Смежные вопросы