niedziela, 7 października 2012

[HTML|JS|CSS] AngularJS: Services

Dzięki zastosowaniu serwisów AngularJS wspiera wzorzec projektowy Dependency Injection. Wzorzec ten znany z wielu obiektowych języków programowania ułatwia testowanie komponentów oraz podejmowanie decyzji o zależnościach w czasie pracy aplikacji. W przypadku Angulara podczas uruchomienia strony tworzony jest obiekt zwany injectorem, zarządzający wszystkimi serwisami. W momencie, gdy chcemy wykorzystać któryś z serwisów, injector zwraca jego instancję lub inicjuje go, jeśli nie nastąpiło to wcześniej. Ma tu więc miejsce połączenie wzorców singletonu oraz lazy-load. Samo wstrzykiwanie zależności można uzyskać na dwa sposoby: niejawnie podając nazwę serwisu jako argument funkcji (np. kontrolera), lub mechanizmem wstrzykiwania. Sposób pierwszy, choć czytelniejszy, napotyka jedną poważną przeszkodę. Podczas minifikacji i obfuskacji pliku ze skryptem zostają zmieniane nazwy zmiennych, również argumentów funkcji, przez co będziemy mieli do czynienia z zupełnie inną logiką. Drugi zapis, nieco dłuższy naprawia ten problem, kosztem czytelności kodu.
//DEPENDENCY INJECTION

function firstController($scope, $window){
 $scope.text = "firstController";
 $scope.introduce = function(e){
  $window.alert($scope.text);
 }
}

function secondController(s, w){
 s.text = "secondController";
 s.introduce = function(e){
  w.alert(s.text);
 }
}
secondController.$inject = ['$scope','$window'];

Mamy także możliwość tworzenia własnych serwisów dla naszych modułów. Dostarczając definicję, dostajemy w prezencie opisaną powyżej funkcjonalność, łącznie z możliwością wstrzykiwania naszego serwisu do kontrolera. Przykład poniżej.
angular.module('services', [], function($provide) {
    $provide.factory('mylogger', function() {
     var counter = 0;
     return function(text){
      counter += 1;
      console.log("Logging text number " + counter);
      console.log(text);
     }
    });
});

Przykład użycia w kontrolerze:
function firstController($scope, $window){
 $scope.text = "firstController";
 $scope.introduce = function(e){
  $window.alert($scope.text);
 }
}

Przez konwencję zaleca się, by nie nadawać własnym serwisom nazw rozpoczynających się od $, jako znaku zarezerwowanego dla serwisów Angulara.

Brak komentarzy:

Prześlij komentarz