2013-08-28 16 views
73

Sto provando a definire le costanti con altre costanti, ma sembra che non possa essere fatto, perché la costante iniziale non è pronta quando la costante richiesta dipendente lo richiede. Voglio essere sicuro che questo non sia affatto possibile.esiste un modo in Angularjs per definire le costanti con altre costanti?

Attualmente ho costanti in questo modo:

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

I secondi due costanti è quello che voglio realizzare

risposta

44

Il modo angolare di definire le dipendenze tra i controllori, servizi e altri è di iniezione di dipendenza (DI). Quindi se hai un controller A che dipende da un servizio B dovresti crearlo in questo modo.

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

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

Vedere, angular controllerà la dipendenza del servizioB e cercherà il servizio creato con quel nome. Se non lo crei, otterrai un errore.

Quindi, se si desidera creare una costante A che dipende dalla costante B, è necessario dire angolare che A dipende da B. Ma la costante non può avere dipendenza. La costante può restituire una funzione, ma il DI non funzionerà per la costante. Controlla questo Fiddle in modo da poter vedere per quali metodi DI funziona: http://jsfiddle.net/RMj5s/1/

Quindi, rispondendo alla tua domanda, non puoi definire una costante con altre costanti.

Ma si può fare questo:

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; 

    }); 

Controllare questo violino vederlo lavorare: http://jsfiddle.net/kJ3tT/1/

Se si vuole capire di più su DI, controllare questo post: http://merrickchristensen.com/articles/javascript-dependency-injection.html

Spero che questo possa rispondere alla tua domanda.

3

Non si può dire con certezza se questo è (im) possibile. Ma una soluzione alternativa sarebbe definire le costanti di base come costanti regolari e quelle di ordine superiore come servizi che utilizzano le chiusure per assicurarsi che non possano essere alterate.

esempio ruvida:

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

E utilizzarlo dopo l'iniezione del servizio:

MyServiceName.GET_SECOND_ORDER_CONST(); 

Non molto elegante, ma dovrebbe ottenere il lavoro fatto.

12

lo faccio in questo modo:

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

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

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

@Beterraba. Potresti approfondire questo? Dove andrebbe questo codice? Grazie. Mark – mark1234

+0

@ mark1234 Questo codice può andare dove vuoi. Mi piace metterlo nel mio file dei servizi. Devi ricordare di includere il modulo 'constants' sul tuo modulo principale. – Beterraba

143

Un modo semplice per farlo è come questo:

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

e utilizzare le costanti di questo tipo:

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

crediti: link

+3

@Helzgate Questo non è quello che stava dicendo @ gabn88. La funzione passata a 'myApp.constant' è un'espressione di funzione immediatamente richiamata, o IIFE. Si chiama così non devi! Assomiglia a questo: '(function (params) {// do stuff})()'. Notare le parentesi attorno all'espressione di funzione e il set extra alla fine. – daemonaka

+0

@Helzgate La costante con il nome "RISORSE" non sarà un'espressione di funzione, quindi, ma * l'oggetto restituito da * quella funzione. – daemonaka

+2

Miglior risposta disponibile. –

8

Finché non è necessario accesso alla tua costante nei fornitori, questo dovrebbe funzionare bene:

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

Se avete bisogno di accesso a voi costanti a fornitori, allora credo che devi fare un po 'più di lavoro:

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

Questa risposta dovrebbe ottenere più amore :). Grazie;) –

2

La soluzione fornita da @Linkmichiel è buono, ma se si cercano disperatamente di utilizzare una costante all'interno un'altra, è possibile combinarli nel blocco di configurazione:

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>

Dopo la fase di configurazione, tutte le costanti saranno configurazione corr ectly (prova lo snippet).

La morale della storia è: Angolare è così bello che puoi perfino cambiare le costanti.

+1

Come complemento. Devi declara 'for (prop in RESOURCES) {' usando var o let, come 'for (lascia prop in RISORSE) {'. – josivan

1

is there a way in Angularjs to define constants with other constants?

Premessa Odio negozio sola costante in ogni dichiarazione .constant, di solito io uso la seguente sintassi per memorizzare tutte le costanti in un un'unica dichiarazione:

.constant("SampleConst", { 
    Types: { 
     "A": "toggle",  
     "B": "run", 
     "C": "close", 
    }, 
    "MenuItems": [ 
     { 
      code: 100, 
      type: "toggle"  //Here I'd like use Types defined before 
     }, 
     { 
      code: 200, 
      type: "toggle"  //Here I'd like use Types defined before 
     }, 
    }], 
    "Nationalities": ["I", "E", "S"], 
    "OtherCost": "TEST", 
}) 

Questa è la mia soluzione per memorizzare le costanti e utilizzare la stessa costante all'interno degli altri

.constant("SampleConst", function() { 

    var _types = { 
      TOGGLE: "toggle",  
      RUN: "run", 
      CLOSE: "close", 
    }; 



    var constants = { 
     Types: _types , 
     MenuItems: [ 
      { 
       code: 100, 
       type: _types.TOGGLE  //NOW USING CONSTANT 
      }, 
      { 
       code: "200", 
       type: _types.RUN   //NOW USING CONSTANT 
      } 
     ], 
     Nationalities: ["I", "E", "S"], 
     OtherCost: "TEST" 
    }; 
    return constants; 

    }()   // <----- Be careful to place double() at the end 
)