Pregunta ¿Hay alguna manera en Angularj para definir constantes con otras constantes?


Estoy tratando de definir constantes con otras constantes, pero parece que no se puede hacer, porque la constante inicial no está lista cuando la constante requerida depende de ello. Quiero estar seguro si esto no es posible en absoluto.

Actualmente tengo constantes de esta manera:

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

Las segundas dos constantes es lo que quiero lograr


73
2017-08-28 17:05


origen


Respuestas:


La forma angular para definir dependencias entre Controladores, Servicios y otros es mediante inyección de dependencia (DI). Entonces, si tienes un controlador A que depende de un servicio B, deberías crearlo así.

var myApp = angular.module("exampleApp",[]);

myApp.controller("aCtrl", function(serviceB){
    //Controller functionally here
});

Ver, angular verificará la dependencia serviceB y buscará el servicio que creó con ese nombre. Si no creas uno, obtendrás un error.

Entonces, si quieres crear una constante A que dependa de la constante B, necesitarás decirle a angular que A depende de B. Pero la constante no puede tener dependencia. Constant puede devolver una función, pero la DI no funcionará para la constante. Verifique este violín para que pueda ver para qué métodos DI funciona: http://jsfiddle.net/RMj5s/1/

Entonces, al responder a su pregunta, no puede definir una constante con otras constantes. 

Pero puedes hacer esto:

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;

  });

Mira este violín para verlo funcionando: http://jsfiddle.net/kJ3tT/1/

Si quieres saber más sobre DI, echa un vistazo a esta publicación: http://merrickchristensen.com/articles/javascript-dependency-injection.html

Espero que esto pueda responder tu pregunta.


44
2018-05-08 14:18



Una manera fácil de hacer esto es así:

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

Y usa las constantes como esta:

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

Créditos: enlazar


145
2017-10-24 13:49



Lo hago de esta manera:

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

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

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

12
2017-08-28 17:53



Siempre que no necesite acceder a su constante en los proveedores, esto debería funcionar bien:

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

Si necesita acceder a sus constantes en los proveedores, entonces creo que debe hacer un poco más de trabajo:

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

8
2018-05-29 08:48



No puedo decir con certeza si eso es (im) posible. Pero una solución alternativa sería definir las constantes básicas como constantes regulares, y las de orden superior como servicios que usan cierres para asegurarse de que no se puedan modificar.

Ejemplo aproximado:

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

Y úsala después de inyectar el servicio:

MyServiceName.GET_SECOND_ORDER_CONST();

No es muy elegante, pero debería hacer el trabajo.


4
2017-08-28 17:47



La solución proporcionada por @Linkmichiel es buena, pero si desea desesperadamente usar una constante dentro de otra, puede combinarlas en el bloque de configuración:

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>

Después de la fase de configuración, todas las constantes se configurarán correctamente (pruebe el fragmento).

La moraleja de la historia es: Angular es tan genial que incluso puedes cambiar las constantes.


2
2017-07-12 14:13