AngularJS : 팩토리 $ http.get JSON 파일


84

하드 코딩 된 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" }
            ]
        }
    ]
}

JSON이 공장 내부에서 하드 코딩되었을 때 컨트롤러, 공장 및 html이 작동했습니다. 그러나 이제 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 콘솔에 출력이 있습니까?
Josh Lee

콘솔에 "리소스를로드하지 못했습니다"라고 표시되고 console.json 파일 경로가 있습니다. 그래서 어떤 이유로 그것을로드하지 않습니다. 내 공장과 JSON은 위에서 본 것과 똑같습니다. JSON을 공장에 하드 코딩하면 작동합니다.
jstacks

1
백엔드로 무엇을 사용하고 있습니까? NodeJ 또는 간단한 파이썬 기반 서버 또는 다른 것?
callmekatootie

백엔드 (Rails)를 제외하고 개발하려고합니다. 따라서 JSON은 위의 데이터가 하드 코딩 된 .json 파일입니다. 아마도 백엔드가 렌더링하는 것과 유사합니다.
jstacks

응답에 ".data"가 필요하지 않을 수 있습니다. 반환 된 JSON이 'data'개체 내에 번들로 제공되지 않는 한 "return response;"로 변경합니다.
Bhaskara 켐파이야

답변:


218

좋습니다. 다음은 살펴볼 사항 목록입니다.

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) {

따라서 function (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');
});

그런 다음 컨트롤러의 계산에서 값을 비동기 적으로 사용할 수 있습니다.

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

27
이봐 그것은 같은 가격에 대한 응답과 각도 $ http 코스입니다-좋은 대답!
Mat

4
4)의 설명에서 $ http.get ()이 해결되기 전에 'return obj'가 호출되지 않습니까? 그게 나에게 일어나는 일이라고 생각하기 때문에 묻는 것뿐입니다.
Pathsofdesign 2014 년

3
네, 그렇습니다. 그러나 $ http.get ()이 해결 될 때 호출되는 클로저는 'obj'에 대한 참조를 유지합니다. 그러면 사용할 수있는 콘텐츠 속성이 채워집니다.
Karen Zilles 2014 년

# 4를 사용하는 것보다 # 3의 두 번째 형식을 사용하는 것이 문제가되는 것은 무엇입니까?
Spencer

1
체인 콜백 .success ()는 더 이상 사용되지 않습니다. 대신 .then (success, error)를 사용하십시오.
Timothy Perez

21

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

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

내가 사용하지 않는 이유 successerror난 그냥에서 발견이다 문서는 ,이 두 가지 방법이 사용되지 않습니다.

$http기존의 약속 방법의 성공과 오류가 사용되지 않습니다. then대신 표준 방법을 사용하십시오 .


2
return $http.get('content.json');공장에서 사용 합니다. 그렇지 않으면 반환 값이 null입니다.
Francesco

2
이봐 요, 잠시만 요. 그것이 작동하는 이유는 (여기에 귀하의 답변과 달리) 객체에 대한 참조를 반환하기 때문입니다. 성공 함수에는 동일한 객체에 대한 참조도 있습니다. ajax 함수가 결국 반환하면 반환 된 원래 객체의 "content"속성을 업데이트합니다. 시도 해봐. :-)
Karen Zilles 2015 년

1
Ps .success는 이제 더 이상 사용되지 않습니다. .then대신 사용하십시오 . docs.angularjs.org/api/ng/service/$http
redfox05

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 2014-08-03

컨트롤러에서이 작업을 수행하지 마십시오! 나쁜! 이것을 서비스로 작성해야합니다. json 값을 호출하는 방식이 틀린 것은 아니지만 컨트롤러에서이를 수행하지 않는 약속을 반환하는 서비스가 있어야합니다. 재사용 성 관점에서도 이것은 끔찍합니다. 예를 들어, 컨트롤러를로드 할 때마다 $ http.get ()을 수행하고 서비스에 캐시 된 버전의 호출을 사용합니다.
Downpour046

1

나는 대략 이러한 문제가 있습니다. Visual Studio 2013에서 AngularJs 응용 프로그램을 디버그해야합니다.

기본적으로 IIS Express는 로컬 파일 (예 : json)에 대한 액세스를 제한했습니다.

그러나 먼저 JSON에는 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>)

다음으로로드 된 데이터를 일반적인 방식으로 사용합니다. 물론 해결 방법 일뿐입니다.


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

최신 정보

나를 위해 일한 더 쉬운 방법은 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"
   }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.