프로그래밍 언어/HTML,CSS,JS

AngularJS : Initialize service with asynchronous data

Rateye 2021. 9. 16. 11:54
728x90
반응형
질문 : AngularJS : 비동기 데이터로 서비스 초기화

비동기 데이터로 초기화하려는 AngularJS 서비스가 있습니다. 이 같은:

myModule.service('MyService', function($http) {
    var myData = null;

    $http.get('data.json').success(function (data) {
        myData = data;
    });

    return {
        setData: function (data) {
            myData = data;
        },
        doStuff: function () {
            return myData.getSomeData();
        }
    };
});

myData 가 돌아 오기 전에 doStuff() 를 호출하려고하면 null 포인터 예외가 발생하기 때문에 분명히 이것은 작동하지 않습니다. 여기여기에서 묻는 다른 질문 중 일부를 읽음으로써 알 수있는 한 몇 가지 옵션이 있지만 그중 어느 것도 매우 깨끗해 보이지 않습니다 (아마도 뭔가 빠진 것 같습니다).

"실행"으로 서비스 설정

내 앱을 설정할 때 다음을 수행하십시오.

myApp.run(function ($http, MyService) {
    $http.get('data.json').success(function (data) {
        MyService.setData(data);
    });
});

그러면 내 서비스는 다음과 같습니다.

myModule.service('MyService', function() {
    var myData = null;
    return {
        setData: function (data) {
            myData = data;
        },
        doStuff: function () {
            return myData.getSomeData();
        }
    };
});

이것은 어느 정도 작동하지만 비동기 데이터가 모든 것을 초기화하는 데 걸리는 시간보다 오래 걸리면 doStuff()

Promise 객체 사용

이것은 아마도 작동 할 것입니다. 유일하게 내가 doStuff ()는 약속과 코드가 우리에게이 모든 반환 알고해야합니다 내가이면 MyService 전화 사방으로 하락 then 약속과 상호 작용을. 내 응용 프로그램을로드하기 전에 myData가 돌아올 때까지 기다리는 것이 좋습니다.

수동 부트 스트랩

angular.element(document).ready(function() {
    $.getJSON("data.json", function (data) {
       // can't initialize the data here because the service doesn't exist yet
       angular.bootstrap(document);
       // too late to initialize here because something may have already
       // tried to call doStuff() and would have got a null pointer exception
    });
});

전역 자바 스크립트 변수 JSON을 전역 자바 스크립트 변수로 직접 보낼 수 있습니다.

HTML :

<script type="text/javascript" src="data.js"></script>

data.js :

var dataForMyService = { 
// myData here
};

MyService 초기화 할 때 사용할 수 있습니다.

myModule.service('MyService', function() {
    var myData = dataForMyService;
    return {
        doStuff: function () {
            return myData.getSomeData();
        }
    };
});

이것도 작동하지만 나쁜 냄새가 나는 전역 자바 스크립트 변수가 있습니다.

이것이 나의 유일한 옵션입니까? 이 옵션 중 하나가 다른 옵션보다 낫습니까? 나는 이것이 꽤 긴 질문이라는 것을 알고 있지만 모든 옵션을 탐색하려고 노력했음을 보여주고 싶었습니다. 어떤 지침이라도 대단히 감사하겠습니다.

답변

$routeProvider.when('/path',{ resolve:{...} 나요? promise 접근 방식을 좀 더 깔끔하게 만들 수 있습니다.

서비스에서 약속을 노출하십시오.

app.service('MyService', function($http) {
    var myData = null;

    var promise = $http.get('data.json').success(function (data) {
      myData = data;
    });

    return {
      promise:promise,
      setData: function (data) {
          myData = data;
      },
      doStuff: function () {
          return myData;//.getSomeData();
      }
    };
});

경로 구성에 resolve 을 추가하십시오.

app.config(function($routeProvider){
  $routeProvider
    .when('/',{controller:'MainCtrl',
    template:'<div>From MyService:<pre>{{data | json}}</pre></div>',
    resolve:{
      'MyServiceData':function(MyService){
        // MyServiceData will also be injectable in your controller, if you don't want this you could create a new promise with the $q service
        return MyService.promise;
      }
    }})
  });

모든 종속성이 해결되기 전에 컨트롤러가 인스턴스화되지 않습니다.

app.controller('MainCtrl', function($scope,MyService) {
  console.log('Promise is now resolved: '+MyService.doStuff().data)
  $scope.data = MyService.doStuff();
});

plnkr에서 예제를 만들었습니다 : http://plnkr.co/edit/GKg21XH0RwCMEQGUdZKH?p=preview

출처 : https://stackoverflow.com/questions/16286605/angularjs-initialize-service-with-asynchronous-data
728x90
반응형