javascript - 如何参数化模块,以便它可以按需配置需要它的应用程序?

标签 javascript angularjs dependency-injection module

关于 harvested framework 的图案,我想将我的 AngularJS 应用程序的配置和实用程序分解为一个独立的模块,例如:

angular.module("configurer", [])
.config(["$httpProvider", function($httpProvider) {

  $httpProvider.defaults.headers.common["Accept"] = "application/hal+json";

}]);

然后,在我的应用程序中:

angular.module("app", ["configurer"]);
<小时/>

我想添加可选 CSRF 保护:

angular.module("configurer", [])
.config(["$httpProvider", function($httpProvider) {

  $httpProvider.defaults.headers.common["Accept"] = "application/hal+json";

  if (applicationWantsCsrfProtection) {
    // implement CSRF protection
  }

}]);

问题是,如何设置这个applicationWantsCsrfProtection变量?

<小时/>

我尝试遍历常量:

angular.module("configurer", [])
.config(["$injector", "$httpProvider", function($injector, $httpProvider) {

  $httpProvider.defaults.headers.common["Accept"] = "application/hal+json";

  if ($injector.has("Application")) {
    var Application = $injector.get("Application");
    if (Application.hasOwnProperty("CSRF")) {
      // implement CSRF protection with Application.CSRF.* attributes
    }
  }

}]);

然后,在我的应用程序中:

angular.module("app", ["configurer"])
.constant("Application", {
  CSRF: {
    headerName: "X-CSRF-TOKEN",
    cookieName: "APP-CSRF-TOKEN"
  }
});

但是 $injector.has("Application") 始终返回 false,无论 Application 常量是否在应用程序中定义或不是:

http://plnkr.co/edit/8RFwqvs6Tmp9gpGkUq7W?p=preview

最佳答案

我通过提供商找到了解决方案:

(function(angular) {

  var config = function($injector) {
    console.log("configurer config has Application: " + $injector.has("Application")); // true
  };

  var run = function($injector) {
    console.log("configurer run has Application: " + $injector.has("Application")); // true
  };

  angular.module("configurer", [])

  .provider("init", function() {
    return {
      config: config,
      $get: function() {
        return {
          run: run
        }
      }
    }
  });

})(angular);

然后,在应用程序中:

angular.module("app", ["configurer"])

  .constant("Application", {
    CSRF: {
      headerName: "X-CSRF-TOKEN",
      cookieName: "APP-CSRF-TOKEN"
    }
  })

  .config(function(initProvider, $injector) {
    initProvider.config($injector);
  })

  .run(function(init, $injector) {
    init.run($injector);
  });

http://plnkr.co/edit/c301t8TN8TfWcn52Kit2?p=info

<小时/>

此解决方案的一个优点是配置器子模块可以扩展配置器行为而无需修改应用程序:

(function(angular) {

  var config = function($injector) {
    console.log("subConfigurer config has Application: " + $injector.has("Application")); // true
  };

  var run = function($injector) {
    console.log("subConfigurer run has Application: " + $injector.has("Application")); // true
  };

  angular.module("subConfigurer", ["configurer"])

  .config(function(initProvider) {

    var configCallfront = initProvider.config;    
    initProvider.config = function($injector) {
      configCallfront($injector);
      config($injector);
    };

    var runCallfront = initProvider.$get().run;
    initProvider.$get = function() {
      return {
        run: function($injector) {
          runCallfront($injector);
          run($injector);
        }
      }
    };

  });

})(angular);

http://plnkr.co/edit/GQKcMK7RkTEwK0YEfAiW?p=info

<小时/>

尽管如此,仍然愿意接受批评或更好的解决方案!

关于javascript - 如何参数化模块,以便它可以按需配置需要它的应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31708260/

相关文章:

angular - 在组件模板中使用服务中的静态函数

css - 用于光标手抓取的 AngularJS Bootstrap CSS 入口

javascript - 在所有页面中包含 Menu.html

javascript - AngularJS ng-click 在编译尝试后未触发

java - JSR 330 和 Guice 互操作性

java - Guice:如何避免模块冗余

javascript - 如何在 map 应用中实现稳定的缩放

javascript - elementExplorer 字符转义在 Protractor 1.8.0 和 2.0.0 上回归?

javascript - Controller 未从工厂返回数据

javascript - 如何从迁移生成 Sequelize 模型?