在angularJS中覆盖模块值/常量的最佳方法

Posted

技术标签:

【中文标题】在angularJS中覆盖模块值/常量的最佳方法【英文标题】:Best way to override module values/constants in angularJS 【发布时间】:2014-04-09 15:57:06 【问题描述】:

我用 angularJS 编写了一个模块,它封装了所有后端通信。为了获得更大的灵活性,我将 api 前缀作为模块上的常量值(可能是值,因为我没有在配置阶段使用它)。 所以像

angular.module('myapp.data').constant('apiPrefix', '/api/data');

现在我想从两个不同的应用程序中使用这个模块。一个使用 /api1/data,另一个使用 /api2/data,我想在应用程序的配置阶段更改它。 我知道如何使用提供者来做到这一点,但让提供者持有价值对我来说似乎有点过头了。我可以在应用程序配置阶段修改使用的模块常量或值吗?

类似:

angular.module("data", [])
.value('apiPrefix', '/api/data')
.factory('display', function(apiPrefix)
  return 
    pref: function()
      console.log(apiPrefix);
      return apiPrefix;
    
  
);


angular.module("myApp",['data'])
.config(['apiPrefix', function(prefix)
  prefix = 'https:/api/data'; 
])
.controller("Example", function($scope, display) 
   $scope.prefix = display.pref;
);

【问题讨论】:

不确定,但您可以尝试在run 阶段进行。 是的,你可以在运行阶段更新一个值,你可以在配置中注入一个常量,但因为它是一个常量,所以不能更改***.com/questions/13035568/… 那么你的意思是它应该是一个值而不是模块中的常量,并在应用程序的运行阶段而不是配置修改它? 你为什么不试一试:) 确实是我们要说的。 Config 需要在可能有 config 的所有东西上运行,然后才能注入任何东西,因此会出现问题。 【参考方案1】:

要覆盖模块值,您可以在以后的模块中重新定义角度值。我相信它不应该在模块配置时间完成。

angular.module("data", [])
.value('apiPrefix', '/api/data')
.factory('Display', function(apiPrefix)
  return 
    pref: function()
      return apiPrefix;
    
  
);




angular.module('myapp', ['data'])
  .value('apiPrefix', '/api2/data')
  .controller('MainCtrl', function($scope, Display)    
      $scope.name = Display.pref();
  );

在此处查看 plunker: http://plnkr.co/edit/k806WE

同样的事情也适用于角度常数。

【讨论】:

很好的解决方案。我有点不知道,因为我可能不小心覆盖了模块常量或值,因为我经常使用它们。好在我一直在尝试创建独特的描述性名称。 谢谢@mxa055。实际上,我更喜欢将常量和值(例如配置或后端 api 端点)保存在单独的配置模块中。【参考方案2】:

我们的模块

angular.module("data", [])
  .constant('apiPrefix', '/api/data');

我们可以完全覆盖constant,例如value

angular.module('myapp', ['data'])
  .constant('apiPrefix', '/api2/data');

我们也可以完全覆盖config

angular.module('myapp', ['data'])
    .config(function ($provide) 
        $provide.constant('apiPrefix', '/api2/data');
    );

我们也可以在run 中完全或部分覆盖(如果是对象)

angular.module('myapp', ['data'])
    .run(function (apiPrefix) 
        apiPrefix = '/api2/data';
    );

但是如果我们想在配置中(而不是在运行中)用部分对象覆盖constant,我们可以这样做

angular.module("module1", [])
    .constant('myConfig', 
        param1: 'value1' ,
        param2: 'value2'
    );

angular.module('myapp', ['data'])
    .config(function ($provide, myConfig) 
        $provide.constant(
            'myConfig', 
            angular.extend(myConfig, param2: 'value2_1');
        );
    );

【讨论】:

使用字符串引用 myConfig 以覆盖模块 myapp 上的扩展值。 angular.module('myapp', ['data']) .config(function ($provide, myConfig) $provide.constant(myConfig, angular.extend('myConfig', param2: 'value2_1'); ) ; ); 谢谢。是的,$provide.constant('myConfig', ... - 'myConfig' 必须是字符串!【参考方案3】:

Angular 模块、控制器等可以包含在函数、if 语句等中。它们不必位于顶层。因此,您可以将其包含在您的代码中:

if (environmentOne()) 
  module.value('apiPrefix','api1/data');
 else 
  module.value('apiPrefix','api2/data');

希望有帮助!

【讨论】:

这听起来很有趣,但我不想在我的模块中为每个可能使用我的不同应用程序做类似的事情。它没有在模块及其用户之间创建“依赖关系”。 啊,你是对的。我误读了您的问题,并认为这是开发/登台/生产环境的问题。 Khanmizan 的答案更好。

以上是关于在angularJS中覆盖模块值/常量的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在测试中覆盖模块配置函数的常量?

番外篇01:angularJS最佳实战

在这种情况下,在 AngularJS 中处理事件的最佳方法是啥?

在运行时更改AngularJs中背景图像的最佳方法

使用gulp将业力测试分成可运行的块的最佳方法是什么?

使用 angularjs 播放 rtmp 流的最佳方法是啥?