2014-11-07 9 views
11

GET 요청에 응답하여 내 angularjs 앱을 초기화 할 수 있습니까? 예를 들어

: -

angular.module('A',[]); 
    angular.module('A').run(function ($rootScope,$http){ 
     $rootScope.safeApply = function (fn) { 

       $http.get('url').success(function(result){ 

        // This doesn't work. I am not able to inject 'theConstant' elsewhere in my application 
        angular.module('A').constant('theConstant', result); 
       });     
       var phase = $rootScope.$$phase; 
       if (phase === '$apply' || phase === '$digest') { 
        if (fn && (typeof (fn) === 'function')) { 
         fn(); 
        } 
       } else { 
        this.$apply(fn); 
       } 
      }; 
     }); 

내 응용 프로그램 초기화다면 상수를 설정하고 내 구성 요소에 상수를 공유 할 수 있어야합니다.

이 작업을 수행하는 가장 좋은 방법은 무엇입니까?

+0

'theValueFromHttpCall' 무엇인가? – akonsu

+0

@akonsu 질문이 업데이트되었습니다. 필자의 경우 reponse는 JSON 객체입니다. –

+0

흥미 롭습니다. 인젝터에는 부팅 할 때 이미 정의 된 모든 구성 요소가 포함되어 있으므로 시나리오를 사용하려면 직접 함께 작업해야한다고 생각합니다. – akonsu

답변

5

$http.get의 결과는 앱이 초기화되는 동안 사용할 수 없습니다. 서버가 전달할 때만 사용할 수 있습니다. 이런 이유로 단순히 모듈에 그 값을 유지하는 것은 불가능합니다. 당신은 위험을 감수합니다

그러나 할 수있는 일은 서비스에서 $http.get으로 전화를 걸어 상수를 원하는 곳에 서비스를 삽입하는 것입니다. (서비스가 설정 블록에 주입 할 수 없습니다.)

// grab the "constant" 
angular.module('A').factory('almostConstant', function() { 
    return $http.get('url').then(function(response) { 
    return response.data; 
    }); 
}); 

// use the "constant" 
angular.module('A').controller('controller', function($scope, almostConstant) { 
    almostConstant.then(function(data){ 
    $scope.almostConstant = data; 
    }); 
}); 

당신의 almostConstant의 가치가 비동기 특성으로 인해 액세스 할 수있는 약간 어색한 모드. 그것은 단순히 지정되지 않은 시간에 사용할 수 있으므로 동기 방식으로 액세스하려고하면 많은 미묘한 타이밍 버그가 발생할 수 있습니다.


이 작업을 수행하는 방법은 JS 파일에 직접 상수를 쓰는 것입니다. 현재 서버는 'url'에 대한 요청에 값으로 응답 할 수 있습니다. 대신, 당신은 다음과 같은 문자열로 'url.js'에 요청에 대답 할 수 :

angular.module('A').constant('theConstant', result); 

을 결과는 분명히 당신의 상수이다. 예를 들어 백엔드에서 PHP를 사용했다면 다음과 같이 보일 수 있습니다 :

<?php 
    header('Content-Type: application/javascript'); 
    $constant = retrieveMyConstant(); 
?> 
angular.module('A').constant('theConstant', <?php echo $constant; ?>); 

실제로 상수는 JavaScript 값처럼 보입니다. 이 문자열의 경우는 JSON 객체는 단순히 index.html 파일에 url.js을 가리키는 스크립트 태그를 포함 등의 직렬화,이 후

쓰기의 경우, '에 포장.

이 솔루션은 동기식이므로 서버에서 상수를 검색하는 데 시간이 오래 걸리면 페이지로드 시간에 영향을 미칩니다.

+0

필자의 경우 서버 측 웹 페이지가 없다. 그래서 나는 당신이 제안한 첫 번째 접근 방식을 따라야한다고 생각합니다. –

+0

좋은 해결책이 아닌 상수 값을 읽을 때마다 서버를 호출하고 있습니다. – Abhijeet

+0

@Abhijeet 팩토리 메소드는 한 번 호출되므로, 페이지에'$ http.get '에 대한 단일 호출이 이루어 지므로 단일 요청이 서버로 전송됩니다. 간단한 예제로 사용해보십시오. – Tibos

1

표준 각도 라우터 나 UI-Router를 사용하여 '해결'속성을 사용하면 앱을 초기화하는 데 더 좋은 방법이라고 생각했습니다.

이 UI-라우터를 사용하는 동안 않은 방법입니다 -

  1. 이 같은 빈 인라인 템플릿으로 최고 수준의 추상적 인 상태를 정의 : -
$stateProvider.state('root',{ 
    abstract:true, 
    template:'<ui-view/>', 
    resolve : { 
     securityContext : function($http){ 
      return $http.get("/security/context"); 
     } 
    } 
}); 
}); 

속성 해결되어야 할 것은 여러분이 응용 프로그램을 통해 요구되는 것입니다. Like - 보안 토큰, 현재 로그인 한 사용자 등.

  1. 위의 상태에서 상속하는 하위 상태를 정의하십시오. 귀하와 귀하의 모든 부분은 주정부가 관리해야합니다.
$stateProvider.state('root.optosoft.home',{ 
    url:'/home', 
    templateUrl : '/assets/home-module/partial/home/home.html', 
    controller: 'HomeCtrl', 
    resolve : { 
     accounts : function(securityContext){ 
      // Child state wil first wait for securityContext to get resolved first 
     } 
    } 
}); 
5

바와 같이 this blog post 설명, 당신은 일정하게 당신의 응용 프로그램을 부트 스트랩 전에 init을 할 수 있습니다

(function() { 
    var app = angular.module("A", []); 

    var initInjector = angular.injector(["ng"]); 
    var $http = initInjector.get("$http"); 

    return $http.get("/path/to/data.json") 
     .then(function(response) { 
      app.constant("myData", response.data); 
     }) 
     .then(function bootstrapApplication() { 
      angular.element(document).ready(function() { 
       angular.bootstrap(document, ["A"]); 
      }); 
     }); 


}()); 
관련 문제