Angular.js: Est-ce que .value () est la bonne façon de définir une constante à l'échelle de l'application et comment la récupérer dans un contrôleur

87

Salut, je regardais quelques vidéos angular.js et j'ai vu que la méthode value () était utilisée pour définir une sorte de constante à l'échelle du module. par exemple, on peut définir la configuration de la bibliothèque Angular-UI comme suit: (coffeescript)

angular.module('app',[])
.value "ui.config", 
  tinymce:
    theme: 'simple'
    width: '500'
    height: '300'

Et mon application ressemble actuellement à ceci:

window.app = angular.module("app", [ 'ui'])

.config(["$routeProvider", ($routeProvider) ->
  $routeProvider
  .when "/users",
    templateUrl: "assets/templates/users/index.html"
    controller: IndexUsersCtrl

  .otherwise redirectTo: "/users"

])

.value 'csrf', $('meta[name="csrf-token"]').attr('content') #<---- attention here

IndexUsersCtrl = ($scope) ->
  $scope.users = gon.rabl
  console.log "I want to log the csrf value here" #<---- then attention
IndexUsersCtrl.$inject = ['$scope']

Mais je n'arrive pas à obtenir cette valeur en appuyant sur la variable «app» qui correspond au module d'application.

J'ai lu ici sur ST et sur le groupe Google d'angularjs qu'une façon de partager du code commun entre les contrôleurs btwn est via un service, ce concept s'appliquera-t-il ici aussi?

Merci!

Nik So
la source
3
Au cas où vous ne le sauriez pas, le service $ http a des fonctionnalités CSRF. Voir la section "Protection contre la falsification de requêtes intersites (XSRF)" ici: docs.angularjs.org/api/ng.$http
Mark Rajcok

Réponses:

147

Module.value(key, value)est utilisé pour injecter une valeur modifiable, Module.constant(key, value)est utilisé pour injecter une valeur constante

La différence entre les deux n'est pas tant que vous "ne pouvez pas éditer une constante", c'est plus que vous ne pouvez pas intercepter une constante avec $ provide et injecter autre chose.

// define a value
app.value('myThing', 'weee');

// define a constant
app.constant('myConst', 'blah');

// use it in a service
app.factory('myService', ['myThing', 'myConst', function(myThing, myConst){
   return {
       whatsMyThing: function() { 
          return myThing; //weee
       },
       getMyConst: function () {
          return myConst; //blah
       }
   };
}]);

// use it in a controller
app.controller('someController', ['$scope', 'myThing', 'myConst', 
    function($scope, myThing, myConst) {
        $scope.foo = myThing; //weee
        $scope.bar = myConst; //blah
    });
Ben Lesh
la source
4
comment le jeton «myService» s'intègre-t-il dans l'image?
Dave Edelhart le
1
@DaveEdelhart, Désolé, je n'ai pas vu votre question plus tôt. Je viens de l'avoir là-dedans comme exemple de service qui utilise la valeur. Heureusement, Pavel Hlobil est un bon samaritain et il a ajouté quelques annotations à mon code pour rendre cela plus clair.
Ben Lesh
2
Non, ce n'est pas "lecture seule". Si vous y mettez un objet, tout peut modifier les propriétés de cet objet. C'est principalement parce qu'il s'agit de JavaScript, et non à cause d'un problème de conception particulier de la part d'Angular. Cependant, je n'ai pas vu la valeur utilisée d'une manière qui soit modifiée, généralement je viens de la voir utilisée pour des «constantes» injectables.
Ben Lesh
2
Cependant, les constantes ne sont PAS immuables. Vous ne pouvez tout simplement pas les écraser avec une autre injection car $ provide ne les interceptera pas pour la décoration.
Ben Lesh
2
Je sais que c'est une vieille réponse, mais "Module.value (clé, valeur) est utilisé pour injecter une valeur modifiable, Module.constant (clé, valeur) est utilisé pour injecter une valeur constante" ne correspond pas à ng dans son dernière incarnation (1.3.4). La différence entre module.value () et module.constant () est que: une constante () est disponible plus tôt dans le cycle de vie de votre application (pendant la configuration et l'exécution); value () n'est disponible que pendant l'exécution. Le fait qu'ils soient modifiables et où les valeurs modifiées sont visibles dépend de la structure de leur valeur (primitive ou non). docs.angularjs.org/guide/providers#constant-recipe
lukkea
4

J'ai récemment voulu utiliser cette fonctionnalité avec Karma dans un test. Comme le souligne Dan Doyon, la clé est que vous injecteriez une valeur comme un contrôleur, un service, etc. Vous pouvez définir .value sur de nombreux types différents - chaînes, tableaux d'objets, etc. Par exemple:

myvalues.js un fichier contenant une valeur - assurez-vous qu'il est inclus dans votre fichier de configuration karma

var myConstantsModule = angular.module('test.models', []);
myConstantModule.value('dataitem', 'thedata');
// or something like this if needed
myConstantModule.value('theitems', [                                                                                                                                                                                                             
  {name: 'Item 1'},                                                                                                                                                                                                                         
  {name: 'Item 2'},                                                                                                                                                                                                                         
  {name: 'Item 3'}
]);                                                                                                                                                                                                                         

]);

test / spec / mytest.js - il s'agit peut-être d'un fichier de spécifications Jasmine chargé par Karma

describe('my model', function() {
    var theValue;
    var theArray;
    beforeEach(module('test.models'));
    beforeEach(inject(function(dataitem,theitems) {
      // note that dataitem is just available
      // after calling module('test.models')
      theValue = dataitem;
      theArray = theitems;
    });
    it('should do something',function() {
      // now you can use the value in your tests as needed
      console.log("The value is " + theValue);
      console.log("The array is " + theArray);
    });
});
Instantané
la source
2

Vous devez référencer csrfdans votre contrôleurIndexUsersCtrl = ( $scope, csrf )

IndexUsersCtrl.$inject = [ '$scope', 'csrf' ]
Dan Doyon
la source