【问题标题】:How to change Angular factory to resolve before injection如何在注入前更改Angular工厂以解决
【发布时间】:2017-05-10 11:18:07
【问题描述】:

我有一个使用 MapProvider 的现有应用程序,如下所示:

mapModule.factory('MapProvider', ['$injector', function($injector) {
    return $injector.get('GoogleMapsService');        
}]);

此 MapProvider 在整个应用程序中广泛使用,并被注入到各种其他控制器和服务中(正确或错误)。

我现在需要添加一个BaiduMapsService,我已经能够使用它作为测试:

mapModule.factory('MapProvider', ['$injector', function($injector) {
    if(true) {
        return $injector.get('GoogleMapsService');
    } else {
        return $injector.get('BaiduMapsService');
    }
}]);

并相应地翻转if 值。 (这两个服务都使用 TypeScript 接口,因此具有相同的方法)。现在,我需要向 API 添加一个$http 调用,它将根据提供的数据返回要使用的地图。如何使我的工厂异步, 不必将我所有的 MapProvider.someCallHere() 调用更改为 MapProvider.then(m => m.someCallHere())

理想情况下,当MapProvider 在我的应用程序中注入时,它将能够使用异步数据进行解析(仅一次),然后注入必要的服务。

或者,有没有办法推迟/延迟加载 Angular,直到我进行 API 调用并在某处设置一些全局数据?

谢谢。

【问题讨论】:

    标签: javascript angularjs dependency-injection angular-factory


    【解决方案1】:

    您可以推迟应用程序bootstrap(另外,不要使用ng-app,手动执行),直到您从服务器获取数据。我之前在question 上回答过这个问题,但每个案例都有自己的具体细节。

    我通常会在应用程序启动之前在应用程序上声明一个配置值,这对于多租户应用程序非常有用。这样这个首选项值就可以在整个应用程序中用作注入的提供程序。

    例如:

    var app = angular.module('app', []);
    
    // retrieve the $http provider
    var ngInjector = angular.injector(["ng"]);
    var $http = ngInjector.get("$http");
    
    // load config function. Returns a promise.
    function loadConfig(){
        return $http.get("/config.json").then(function(response) {
            // declare the configuration value on your app
            app.constant("Config", response.data);
        }, function(err) {
            console.error("Error loading the application config.", err)
        });
    }
    
    // Call loadConfig then bootstrap the app
    loadConfig().then(function () {
        angular.element(document).ready(function() {
            angular.bootstrap(document, ["app"]);
        });
    });
    

    最后从您的工厂,您可以使用Config 常量来检索首选地图。

    mapModule.factory('MapProvider', ['$injector', 'Config', function($injector, Config) {
        if(Config.preferedMap == 'GoogleMap') {
            return $injector.get('GoogleMapsService');
        } else {
            return $injector.get('BaiduMapsService');
        }
    }]);
    

    【讨论】:

      【解决方案2】:

      我能想到的唯一方法是保持初始化整个angular(和模块),直到你得到你的“配置”(并且设置为全局变量)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多