Angular.js: é .value () a maneira correta de definir a constante ampla do aplicativo e como recuperá-la em um controlador

87

Olá, eu estava assistindo a alguns vídeos do angular.js e vi que o método value () foi usado para definir um tipo de constante em todo o módulo. por exemplo, pode-se definir a configuração da biblioteca Angular-UI assim: (coffeescript)

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

E meu aplicativo está atualmente parecido com este:

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']

Mas não consigo obter esse valor tocando na variável 'app' que corresponde ao módulo do app.

Eu li aqui no ST e no grupo do Google do angularjs que uma maneira de compartilhar controladores btwn de código comum é por meio de um serviço. Esse conceito se aplica aqui também?

Obrigado!

Nik So
fonte
3
Caso você não saiba, o serviço $ http possui alguns recursos CSRF. Consulte a seção "Proteção de Cross Site Request Forgery (XSRF)" aqui: docs.angularjs.org/api/ng.$http
Mark Rajcok

Respostas:

147

Module.value(key, value)é usado para injetar um valor editável, Module.constant(key, value)é usado para injetar um valor constante

A diferença entre os dois não é tanto que você "não pode editar uma constante", é mais que você não pode interceptar uma constante com $ fornecer e injetar outra coisa.

// 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
fonte
4
como o token 'myService' se encaixa na imagem?
Dave Edelhart
1
@DaveEdelhart, Desculpe, não vi sua pergunta antes. Eu apenas tinha lá como exemplo de um serviço que usou o valor. Felizmente, Pavel Hlobil é um bom samaritano e ele adicionou algumas anotações ao meu código para deixar isso mais claro.
Ben Lesh
2
Não, não é "somente leitura". Se você colocasse um objeto lá, qualquer coisa poderia alterar as propriedades desse objeto. Isso ocorre principalmente porque é JavaScript, e não por causa de qualquer preocupação de design particular da parte do Angular. No entanto, não vi valor usado de uma forma que esteja sendo alterado, geralmente acabei de vê-lo usado para "constantes" injetáveis.
Ben Lesh
2
No entanto, as constantes NÃO são imutáveis. Você simplesmente não pode sobrescrevê-los com outra injeção porque $ supply não os interceptará para decoração.
Ben Lesh
2
Eu sei que esta é uma resposta antiga, mas "Module.value (chave, valor) é usado para injetar um valor editável, Module.constant (chave, valor) é usado para injetar um valor constante" não corresponde a ng em seu última encarnação (1.3.4). A diferença entre module.value () e module.constant () é que: uma constant () está disponível no início do ciclo de vida do seu aplicativo (durante a configuração e execução); value () está disponível apenas durante a execução. Se eles são mutáveis ​​e onde os valores alterados são visíveis, depende da estrutura de seus valores (primitivos ou não). docs.angularjs.org/guide/providers#constant-recipe
lukkea
4

Recentemente, eu queria usar esse recurso com Karma dentro de um teste. Como Dan Doyon aponta, a chave é que você injetaria um valor como um controlador, serviço, etc. Você pode definir .value para muitos tipos diferentes - strings, matrizes de objetos, etc. Por exemplo:

myvalues.js um arquivo contendo valor - certifique-se de incluí-lo em seu arquivo conf do 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 - talvez este seja um arquivo de especificações Jasmine carregado pelo 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);
    });
});
Instantâneo
fonte
2

Você precisa fazer referência csrfem seu controladorIndexUsersCtrl = ( $scope, csrf )

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