2014-06-21 4 views
0

속성이 있지만 JavaScript 객체의 속성에 액세스 할 수 없습니다. AngularJS에서 Factory 객체의 속성에 액세스하려고합니다.캔트에 액세스 JavaScript 객체의 속성

angular.module("appManager") 

    // factories.js 
    .factory("DataFactory", function ($http) { 
    var fac = {}; 

    fac.expenses = {}; 
    $http.get("mvc/m/revenue.json") 
     .success(function (result) { 
      console.log(result);   // line 9 
      fac.expenses = result.expenses; 
     }); 
    console.log(fac);      // line 13 
    return fac; 
    }) 

    // expenseController.js 
    .controller("expenseCtrl", function($scope, DataFactory){ 
    $scope.data = DataFactory.expenses; 
    console.log(DataFactory);    // line 4 
    console.log(DataFactory.expenses);  // line 5 
    console.log($scope.data);    // line 6 

    // Global // var d = {}; 
    d = DataFactory; 
    e = DataFactory.expenses; 
    }); 

그리고 콘솔의 OUPUT : 아래 코드는 enter image description here

사람도 이것에 대해 (here) 요청하지만 그는 해결책을하지 않았다. 나는 또한 거기에 제안 된 시도 : 키를 사용하여 콘솔 "정의되지 않은 함수"오류가 throw됩니다. $http 내부의 로그에있는 log() // 9이 다른 함수보다 나중에 호출됨을 알 수 있습니다. 이것이 이유 일 수 있습니까? 그러나 log() // 13 수 있습니다 이미 개체를 인쇄하십시오.

AngularJS에 문제가있을 수 있다고 생각했는데 동일한 결과를 제공하는 테스트 용으로 글로벌 변수 d and e을 시도했습니다. DataFactory["expenses"] 같은 결과

누군가가 내가 뭘 잘못 말해 주시겠습니까 :

는 또한 첨자를 시도?를

+0

CONSOLE.LOG과 같을 것이다 상속 인쇄되지 않습니다 속성 – Ven

+0

@Ven 상속 된 속성은 무엇입니까? –

+0

'd.expenses'에 데이터가 있지만'e'가 없다면,'d.expenses' (또는'DataFactory.expenses') 어딘가가 다른 객체로 바뀌므로'e'와는 다른 것을 의미합니다. – Oriol

답변

2

비동기 호출을 사용하고 있지만 동시에 발생하는 것처럼 처리하려고합니다. 결과를 실제로 요청한 네트워크 호출이 끝나고 반환되기 전에 결과를 사용하려고하면 결국 작동하지 않습니다.

콘솔 명령문의 순서를보십시오. ($http.get() 이후) 13 호선 (.success 핸들러 $http.get())에서 호출이 발생합니다. 그래서 13 호선에 fac.expenses이 아직 할당되어 있지 않습니다. 줄 4,5,6으로 표시된 줄까지도 fac.expenses이 9 번 줄 뒤에 설정됩니다.

비동기 네트워킹 호출에서 작동하도록 코드를 작성하지 않았으므로 제대로 작동하지 않는 것으로 보입니다. 은 .success handler 또는 .success 처리기에서 호출 한 것에서 만 안정적으로 사용할 수 있습니다.

또한 타이밍 관련 문제이므로 툴을 디버깅하여 여러 가지 방법으로 속일 수 있습니다. 일반적으로 부모 객체가 아니라 실제 값을 로그에 기록해야합니다. console.log()은 나중에 로그에 부모 객체로 드릴하려고 할 때 혼동을 줄 수 있기 때문입니다 (채워 졌기 때문에).


나는 확실히 당신이 추천 정확히 알고 여기를 달성하기 위해 노력하고 정확히 수행하지 않습니다,하지만 당신은 fac.expenses을 사용하려는 경우, 당신은해야합니다 중 하나 .success 핸들러 내부에 사용 어디를 처음에 반환되었거나 다른 함수를 호출하고 fac.expenses을 다른 함수에 전달할 수 있습니다. 수행중인 것처럼 비동기 콜백에서 반환 할 수 없으며 이미 실행 된 다른 체인화 된 코드에서도 사용할 수 있습니다.

1

jfriend00이 머리에 못을 박았습니다. DataFactory 서비스에서 빈 객체를 반환하고 Ajax 서비스에서 결과를 얻는다. 비동기 호출의 특성은 코드가 계속 실행되어 서버에서 응답을 기다리는 동안 빈 객체를 반환한다는 것입니다. 비동기는 처음 실행될 때 모든 사람들을 물지 만 나중에 패턴을 인식하게됩니다.

Deferred Promise 패턴이라고 불리는 이것을 다루는 현대적인 방법이 있습니다. Angular의 $ q 서비스는 지연된 개체를 제공합니다.

https://docs.angularjs.org/api/ng/service/ $ q를

그래서 $ q를 사용하여 서비스는 다음과 같이 보일 것이다 :

.factory("dataFactory", ['$http', '$q', function ($http, $q) { 
    var fac = $q.defer(); 

    $http.get("mvc/m/revenue.json") 
     .success(function (result) { 
      fac.resolve(result); 
     });     
     return fac.promise; 
}]); 

다음 컨트롤러가

.controller("expenseCtrl", ['$scope', 'dataFactory', function($scope, dataFactory){ 
    dataFatory.then(function(data) { 
     $scope.data = data.expenses; 
    }); 
}]); 
관련 문제