【问题标题】:Is there a way in AngularJS to define constants with other constants?AngularJS 中有没有办法用其他常量定义常量?
【发布时间】:2013-08-31 21:21:03
【问题描述】:

我正在尝试用其他常量定义常量,但似乎无法完成,因为当所需的常量取决于需要它时,初始常量还没有准备好。我想确定这是否根本不可能。

目前我有这样的常量:

angular.module('mainApp.config', [])
    .constant('RESOURCE_USERS_DOMAIN', 'http://127.0.0.1:8008')
    .constant('RESOURCE_USERS_API', 'http://127.0.0.1:8008/users')
    // Specific routes for API
    .constant('API_BASIC_INFORMATION', RESOURCE_USERS_API + '/api/info')
    .constant('API_SOCIAL_NETWORKS', RESOURCE_USERS_API + '/api/social')
    ;

后两个常量是我想要完成的。

【问题讨论】:

    标签: angularjs angularjs-module


    【解决方案1】:

    一个简单的方法是这样的:

    var myApp = angular.module("exampleApp",[]);
    
    myApp.constant('RESOURCES', (function() {
      // Define your variable
      var resource = 'http://127.0.0.1:8008';
      // Use the variable in your constants
      return {
        USERS_DOMAIN: resource,
        USERS_API: resource + '/users',
        BASIC_INFO: resource + '/api/info'
      }
    })());
    

    并像这样使用常量:

    myApp.controller("ExampleCtrl", function(RESOURCES){
      $scope.domain = RESOURCES.USERS_DOMAIN;
    });
    

    致谢:link

    【讨论】:

    • @Helzgate 这不是@gabn88 所说的。传递给myApp.constant 的函数是立即调用函数表达式或IIFE。它会调用自己,所以你不必!它看起来像这样:(function (params) {//do stuff})()。请注意函数表达式周围的括号和末尾的额外集合。
    • @Helzgate 名称为RESOURCES 的常量因此不是函数表达式,而是由该函数返回的对象
    • 最佳答案。
    • 返回的对象后不应该有一个;分号,例如:return { ..... };我知道虽然基于javascript的自动分号插入,但从技术上讲你不需要分号,@ 987654322@ - 但最佳实践是什么?
    • 为了清楚起见,如果您最终不得不做RESOURCES().USERS_DOMAIN,那么请阅读上面关于立即调用函数表达式 (IIFE) 的 cmets。我认为这就是 Helzgate 的评论内容已被删除?
    【解决方案2】:

    AngularJS 定义控制器、服务和其他之间的依赖关系的方法是依赖注入 (DI)。因此,如果您有一个依赖于服务 B 的控制器 A,则必须像这样创建它:

    var myApp = angular.module("exampleApp",[]);
    
    myApp.controller("aCtrl", function(serviceB){
        // Controller functionally here
    });
    

    你看,AngularJS 会检查 serviceB 的依赖并寻找你用那个名字创建的服务。如果你不创建一个,你会得到一个错误。

    所以,如果你想创建一个依赖于常量 B 的常量 A,你需要告诉 angular A 依赖于 B。但是一个常量不能有依赖关系。常量可以返回函数,但 DI 不适用于常量。检查此Fiddle,以便了解 DI 适用于哪些方法。

    所以回答你的问题,你不能用其他常量定义一个常量。

    但你可以这样做:

    angular.module('projectApp', [])
      .constant('domain', 'http://somedomain.com')
      .constant('api', '/some/api/info')
      .service('urls', function(domain, api) {this.apiUrl = domain + api;})
    
      .controller('mainCtrl',function($scope,urls) {
    
          $scope.url = urls.apiUrl;
    
      });
    

    检查此fiddle 以查看它是否正常工作:

    如果您想了解有关 DI 的更多信息,请查看此post

    【讨论】:

      【解决方案3】:

      我是这样做的:

      var constants = angular.module('constants', []);
      
      constants.factory("Independent", [function() {
         return {
            C1: 42
         }
      }]);
      
      constants.factory('Constants', ["Independent", function(I) {
         return {
            ANSWER_TO_LIFE: I.C1
         }
      }]);
      

      【讨论】:

      • @Beterraba。你能详细说明一下吗?这段代码会去哪里?谢谢。标记
      • @mark1234 这个代码可以去任何你想去的地方。我喜欢把它放在我的服务文件中。您必须记住在主模块中包含 constants 模块。
      【解决方案4】:

      只要您不需要访问提供程序中的常量,这应该可以正常工作:

      .constant('HOST', 'localhost')
      .factory('URL', function(HOST) { return "http://" + HOST })
      

      如果您需要访问提供程序中的常量,那么我想您还需要做一些工作:

      .constants('HOST', 'localhost')
      .provider('DOMAIN', function(HOST) {
          var domain = "http://" + HOST;
          this.value = function() { return domain };
          this.$get = this.value;
       })
       .provider("anyOtherProvider", function(DOMAINPovider) {
           var domain = DOMAINProvider.value();
       };
       .factory("anyOtherService", function(DOMAIN) {
       })
      

      【讨论】:

      • 这个答案应该得到更多的爱:)。谢谢;)
      【解决方案5】:

      我无法确定这是否(不可能)。但一种解决方法是将基本常量定义为常规常量,将高阶常量定义为使用闭包的服务,以确保它们不能被更改。

      粗略的例子:

      angular.module('myApp').constant('BASE_CONSTS',{
          'FIRST_CONST': '10',
          'SECOND_CONST': '20'
      });
      
      angular.module('myServices').factory('MyServiceName', ['BASE_CONSTS', function ('BASE_CONSTS') {
          var SECOND_ORDER_CONST = BASE_CONSTS.FIRST_CONST * 100;
          return {
              GET_SECOND_ORDER_CONST: function() {
                  return SECOND_ORDER_CONST;
              }
          }
      }]);
      

      并在注入服务后使用:

      MyServiceName.GET_SECOND_ORDER_CONST();
      

      它不是很优雅,但它应该可以完成工作。

      【讨论】:

        【解决方案6】:

        @Linkmichiel 提供的解决方案很好,但是如果您非常想在另一个常量中使用一个常量,您可以在 config 块中组合它们:

        angular.module("exampleApp", [])
        
        .constant('BASE_URL', 'http://127.0.0.1:8008')
        
        .constant('RESOURCES', {
          USERS_DOMAIN: '',
          USERS_API: '/users',
          BASIC_INFO: '/api/info'
        })
        
        .config(function(BASE_URL, RESOURCES) {
          for (prop in RESOURCES) {
            RESOURCES[prop] = BASE_URL + RESOURCES[prop];
          }
        })
        
        .controller('WhatIsInResourcesController', function($scope, RESOURCES) {
          $scope.RESOURCES = RESOURCES;
        });
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
        <div ng-app="exampleApp">
          <div ng-controller="WhatIsInResourcesController">
            <pre>{{ RESOURCES | json }}</pre>
          </div>
        </div>

        在配置阶段之后,所有的常量都会被正确设置(试试 sn-p)。

        这个故事的寓意是:Angular 非常酷,你甚至可以更改常量。

        【讨论】:

        • 作为补充。您需要使用 var 或 let 声明 for (prop in RESOURCES) {,例如 for (let prop in RESOURCES) {
        猜你喜欢
        • 1970-01-01
        • 2015-06-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-06
        • 2021-12-17
        • 2012-10-30
        相关资源
        最近更新 更多