AngularJS中是否可以使用其他常量定义常量?


77

我正在尝试用其他常量定义常量,但是似乎无法完成,因为当所需常量依赖于它时,初始常量尚未准备就绪。我想确定这是否完全不可能。

目前,我有这样的常量:

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')
    ;

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

Answers:


45

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对该常数不起作用。选中此小提琴,以便您可以了解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;

  });

检查此小提琴以查看其工作原理

如果您想了解有关DI的更多信息,请查看这篇文章


147

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

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;
});

积分:链接


3
@Helzgate这不是@ gabn88所说的。传递给的函数myApp.constant是立即调用的函数表达式或IIFE。它自称,所以您不必!看起来像这样:(function (params) {//do stuff})()。请注意函数表达式周围的括号和结尾处的多余集。
daemonexmachina 2015年

@Helzgate具有名称的常量RESOURCES因此不是函数表达式,而是该函数返回的对象
daemonexmachina 2015年

2
最佳答案。
Jelle Oosterbosch,2015年

2
;返回的对象后面不应该有分号,例如:return { ..... };我知道,尽管基于javascript的自动分号插入(例如此链接),但从技术上讲您不需要分号-但是最佳实践是什么?
redfox05 '03

为了清楚起见,如果您最终不得不这样做,请RESOURCES().USERS_DOMAIN阅读上面有关立即调用函数表达式(IIFE)的注释。我认为这就是Helzgate关于删除了哪些内容的评论?
redfox05

13

我这样做:

var constants = angular.module('constants', []);

constants.factory("Independent", [function() {
   return {
      C1: 42
   }
}]);

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

@贝特拉巴 您能详细说明一下吗?这段代码会去哪儿?谢谢。马克
mark1234 2014年

@ mark1234此代码可以放在您想要的任何地方。我喜欢将其放在我的服务文件中。您必须记住constants在主模块上包括该模块。
Beterraba 2014年

8

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

.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) {
 })

这个答案应该会得到更多的爱:)。谢谢;)
Nicu Surdu 2016年

4

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

粗略的例子:

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();

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


3

@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>

在配置阶段之后,所有常量都将正确设置(试用代码段)。

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


1
作为补充。您需要for (prop in RESOURCES) {使用var或let进行声明,例如for (let prop in RESOURCES) {
josivan '17
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.