2016-06-02 2 views
0

동적 구성 데이터를 반환하는 WebAPI 서비스가 있습니다. 각도 응용 프로그램이로드되기 전에 해당 서비스를 호출하고 구성 데이터를 각도로로드하려고합니다. JSFiddle 저의 시도 중입니다. 내 질문은 콘솔에서 문자열 테스트를보고 난 후에 콘솔에 쓰여진 내용이 아무것도 없다는 것을 알 수 있습니다. 어떻게 내가 대신 app.run 단계에서이 작업을 실행하지 않는 이유 질문에 대한 응답으로 콘솔http 호출로 수동 부트 스트랩이 있음

var app = angular.module('app', []) 

app.provider("ConfigService", function() { 
    var self = this; 
    self.Settings = {}; 

    self.config = function (data) { 
      console.log(data); 
    }; 
    this.$get = 
     function($http) { 
      return self; 
     }; 
}); 


angular.element(document).ready(function($http) { 
     console.log('test') 
     angular.module('app').config([ 
      'ConfigServiceProvider', 
      function(configService) { 
       console.log('test 2') 
       $http.get('http://www.google.com').then(function(result) { 
        console.log('wierd wierd') 

        configService.config(result); 

        angular.bootstrap(document, ['app']); 
       }) 
      } 
     ]); 
    }); 

편집

로 표시 test 2wierd wierd을받을 수 있나요. app.run 단계에서 앱이 여전히 초기화 중이며 구성 섹션이 완료되기 전에 앱이로드되는 경우가 있습니다. 나는 100 % 보장을 원했고 나의 설정 섹션은 앱이 시작되기 전에 먼저로드되었다.

+1

나는이 실행 단계가 나는 때문에, 실행 단계에서이 작업을 수행하지 않도록 선택 – Katana24

+0

을 시작하는 모든 서비스는 시간에 의해로드 된 것 같은 구성 단계 반대로 실행 단계에서 수행 더 좋은 생각 응용 프로그램이 계속로드되고 때로는 더 빨리로드됩니다. 구성 서비스가 설정에 의존하기 때문에 응용 프로그램의 일부 기능이 중단 된 채로 되돌릴 수 있습니다. – gh9

+0

페이지 서버의 javascript 변수에 데이터를 부트 스트랩해야합니다. (그리고 상수에 넣으면) 또는 구성을 서비스에 넣어야하고 그것에 의존하는 모든 것이 약속을 통해 액세스해야합니다 (거기에 의존 할 수 없기 때문에). 구성 단계 또는 실행 단계에 넣어도 상관 없습니다. – DerekMT12

답변

1

편집 : @StevenWexler의 답변 : https://stackoverflow.com/a/37599857/5670592을 사용하십시오. 그것은 더 정확하고 멋진 각도 기능 ($ inject)을 사용하며 부트 스트랩주기가 시작되기 전에 구성을 제공합니다.

API 호출이 완료 될 때까지 차단 실행과 관련하여 제약 조건으로 애플리케이션을 업데이트했습니다.

이 시도 : https://jsfiddle.net/6svnemu8/3/

은 내가 module.run (...) 블록에 코드를 이동했다. 여기서 모든 공급자를 사용할 수 있으며 $ http 및 ConfigService를 사용할 수 있습니다. 나는 문서 준비 함수에서 부트 스트랩 호출을 유지했으며 API 호출이 완료 될 때까지 응용 프로그램의 실행을 차단할 수 있도록 $ q 서비스를 추가했습니다. 당신은 콘솔의 시험 출력의 순서를 보면이를 확인할 수 있습니다 :

angular.module('app').run([ 
'ConfigService', '$http', '$q', 
function(configService, $http, $q) { 
    console.log('test 2'); 
    var deferred = $q.defer(); 
    $http.get('/6svnemu8/2/').then(function(result) { 
    deferred.resolve(result); 
    }, function(result){ 
    deferred.reject(result); 
    }); 
    console.log("test 3"); 
    deferred.promise.then(function(result){ 
    console.log('wierd wierd'); 

    configService.config(result); 

    }, function(result){ 
    console.log("call failed."); 
    }); 
} 
]); 

+0

앱을 계속로드하고로드하는 것이 더 빠를 때까지 구성 서비스가 돌아올 수 있기 때문에 실행 단계에서이 작업을 수행하지 않기로했습니다. 구성에 의존하여 앱의 일부 기능이 깨졌습니다. – gh9

+0

@ gh9 내 업데이트를 참조하십시오. API 호출이 완료 될 때까지 run 메소드에서 블로킹을 추가했습니다. – Andonaeus

+0

대단히 감사합니다. – gh9

1

옵션 1 - 당신이 당신의 주요 면도기보기에서 MVC 응용 프로그램을

이있는 경우 JSON.Net을 사용하여 모델 (또는 그 속성)을 JavaScript로 직렬화하십시오.

<script> 
    window.configuration = @(Html.Raw(JsonConvert.SerializeObject(Model))) 
</script> 

각도 상수로 입력하면 원하는 곳에 삽입 할 수 있으므로 거기에있을 수 있습니다. 이것이 가장 편리한 방법입니다.

angular.module('YourModule').constant('configuration', window.configuration); 

옵션 2 - 구성을로드하고 약속을 캐시합니다 비동기

이 서비스를로드. 당신은 angular.injector하여 각 모듈의 $http 외부에서 사용할 수

angular.module('YourModule').controller('SomeController', ['configuration', function(configuration) { 
    var vm = this; 

    configuration.get().then(function(config) { 
     vm.someSetting = config.someSetting; 
    }); 
}]); 
3

:

angular.module('YourModule').factory('configuration', ['$http', function($http) { 
    var configurationLoaded; 
    var service = { 
     get: get 
    }; 

    function get() { 
     if(configurationLoaded) return configurationLoaded; 

     configurationLoaded = $http.get(...); 

     return configurationLoaded; 
    } 

    return service; 
}]); 

그럼 어디 당신은 당신이 이런 식으로에서 속성을 꺼내해야합니다, 그것은 필요합니다. $http을 사용하면 $ http의 약속이 해결되면 서버에서 구성을 요청하고 앱을 부트 스트랩 할 수 있습니다.

JS Fiddle

모듈을 서버에서

function fetchConfig() { 
    var $http = angular.injector(["ng"]).get("$http"); 
    return $http.get("http://www.google.com"); 
} 

기능 설정을 가져옵니다

var app = angular.module("app", []); 
app.provider("configService", function() { 
    var configService = { 
    config: {} 
    }; 
    this.setConfig = function (config) { configService.config = config; }; 
    this.$get = function() { return configService; }; 
}); 

기능을 작성하는 부트 스트랩 응용 프로그램

function bootstrap(config) { 
    app.config(["configServiceProvider", function (configServiceProvider) { 
    configServiceProvider.setConfig(config); 
    }]).run(["configService", function (configService) { 
    //Not necessary, just to confirm everything worked 
    console.log("YAY! You have a config:", configService.config); 
    }]); 

    angular.bootstrap(document, ["app"]) 
} 

fetchConfig().then(
    /*sucess*/function (config) { angular.element(document).ready(function() { bootstrap(config); }); }, 
    /*fail*/ function (err) { console.log("UH OH could not retrieve config!", err); }); 
+0

이것은 앵귤 시동 시동 사이클의 외부에서이를 수행하는 훌륭한 솔루션입니다. 이것을 OP에서 필요한 모든 것을 제공하기 위해 내 대답의 $ q 차단 메커니즘과 결합 할 수 있습니다. +1 – Andonaeus

+0

[$ http.get] (https://docs.angularjs.org/api/ng/service/$http) 약속을 반환합니다. 그래서 내 해결책은 http 호출이 부트 스트랩하기 전에 끝나기를 기다린다. –

+0

아 예, 정확하고 훌륭한 답변입니다. – Andonaeus

관련 문제