web-dev-qa-db-fra.com

Filtre personnalisé Angularjs et injection de dépendances

Je suis nouveau sur AngularJS et je vois beaucoup cette syntaxe:

function someFunc(){
   return function(input){
    return 'hello' + input;
  }
}

La fonction ci-dessus est une syntaxe générale que j'ai tendance à voir beaucoup mais le problème est spécifique à cet exemple de filtre personnalisé:

angular.module('bookFilters', [])
    .filter('newBookFilter', function(){
          return function(input){
        return 'The Book: ' + input.name + 'is new !';
   };
});

Je comprends que l'encapsulation de la fonction avec une autre fonction me donne la possibilité d'utiliser l'injection de dépendance, voici mes questions à ce sujet:

Le filtre obtient-il la fonction renvoyée par la fonction d'habillage? Peut-il alors utiliser l'injection de dépendances pour injecter la valeur dans la fonction? Théoriquement que:

Ce code:

{{bookObj | newBookFilter}}

Va devenir:

{{   bookObj | function(input){return 'The Book: ' + input.name + 'is new !'; }  }}

Et enfin le {{}} renverra la valeur finale de la fonction.

Pourquoi ne puis-je pas simplement injecter le input à la première fonction comme:

angular.module('bookFilters', [])
         .filter('newBookFilter', function(input){
             return 'The Book: ' + input.name + 'is new !';
     });

Pourquoi l'injection de dépendances ne fonctionnera que sur la fonction retournée?

Je sais que je suis vraiment confus ici, si quelqu'un peut m'aider, je serai très reconnaissant, merci à tous et bonne journée.

16
Aviel Fedida

Je pense à Angular factory, service, filter, directive wrappers comme des fours qui créent des objets et des fonctions JavaScript avec Angular Flavors. Donc, pour emprunter le même style à Réponse de Vasiliy:

// Don't use this code in a real app. It's just to illustrate a point.
angular.module('App', [])

// The following oven makes an Angular flavored JavaScript function that 
// formats a currency
.service('currencyBadFilterFn',
  // We inject a built-in Angular filter, currencyFilter, into our oven
  function(currencyFilter) { 
    // oven produces a function that can be used in other places in Angular code
    return function(number) {
      // produced function returns a currency-formatted number when used
      return currencyFilter(number)   
    }
  }
)

.controller('MainCtrl',
  function($scope, currencyBadFilterFn) {
    $scope.amount = currencyBadFilterFn(10) // $10.00
  }
)

Comme vous pouvez le voir, le même modèle est utilisé dans la création de services. Ici, nous créons un service qui renvoie une fonction que nous pouvons utiliser à d'autres endroits de notre code.

La première fonction, la fonction four, avec le .service ou .factory ou .filter wrapper, indique Angular comment construire votre fonction. La valeur de retour de cette première fonction est celle que vous utiliserez dans votre code.

11
M.K. Safi

La réponse est opposée à votre question. Angular injecte seulement dans la fonction d'usine mais pas en fonction résultante:

   .filter('newBookFilter', function($log, ...){ // <- factory function
       return function(input, ...){              // <- resulting function
       };
   })

Les fonctions d'usine ont des paramètres injectés arbitrairement. La fonction résultante a des paramètres fixes.

La deuxième raison est que vous pouvez effectuer une initialisation en fonction d'usine. Ceci est utile par exemple lorsque vous définissez nouvelle directive . L'usine renvoie également la fermeture qui peut capturer les variables et les arguments de la fonction d'usine. Voir l'exemple ci-dessous. Il utilise l'injection de dépendances pour obtenir l'objet de journalisation. Ici est un exemple complet.

  .filter('joinBy', function ($log) {     // <- injected here
    return function (input, delimiter) {  // <- used here
      var res = (input || []).join(delimiter || ',');
      $log.info(res);
      return res;
    };
  });
21
Vasiliy Kevroletin

Voilà comment je l'ai fait.

myApp.filter("myCustomDateFormatter", ['MyFactoryWithCustomFunctions', function (InjectedCustomFunction) {
    return function (input) {
        return InjectedCustomFunction.GetDateFromDotNetJson(input);
    }
}]);
1
Mahesh