AngularJS – wstrzykiwanie zależności

bugajsky.pl 6 lat temu

W tym wpisie wytłumaczę czym jest wstrzykiwanie zależności oraz przybliżę metody służące do tego. Opowiem o zaletach i wadach, każdej z nich. Dodatkowo wspomnę o obiekcie $rootScope oraz zaprezentuje jego działanie w aplikacji demonstracyjnej. Wymienie również obiekty jakie mogą być wstrzykiwane.

Wstrzykiwanie zależności to wzorzec projektowy, służący do zarządzania zależnościami. Korzystając z tego mechanizmu mamy większą kontrole nad czytelnością pisanego przez nas kodu. Wynika to z tego, iż tworzenie jak i używanie zależności są od siebie oddzielone. Możemy z obiektu korzystać w różnych miejscach pisanej aplikacji. Dodatkowo mamy możliwość modyfikacji zależności poprzez dodanie nowej lub usuniecie już istniejącej. Ilość wstrzykiwanych zależności jest dowolna.

Dostęp do zależności

Do obiektu możemy się odwołać dzięki trzech sposobów

  1. Ze zmiennej globalnej – $rootScope.
  2. Ze zmiennej lokalnej – $scope.
  3. Poprzez przekazanie parametru do funkcji wykonującej.

$rootScope to obiekt przechowujący wszystkie instancje obiektów $scope, które są jego potomkami. Jednak warto pamiętać, iż nie należy zaśmiecać globalnego zbioru.

Zmienne lokalne – $scope wymagają tworzenia w miejscu wywołania, co pozbawia możliwości zarządzania zależnościami.

Zatem wstrzykiwanie zależności związane jest z przekazywaniem ich przez parametr. Za wstrzykiwanie odpowiada usługa $injector.

Metody wstrzykiwania zależności

W celu wstrzyknięcia zależności mamy do dyspozycji trzy sposoby:

  1. Implicit Annotation
  2. Explicit Annotation
  3. Usługa $injector

Implicit Annotation

Najprostsza konstrukcja odpowiadająca za wstrzykiwanie zależności. Polega na przekazaniu obiektów jako parametr funkcji tworzącej komponent np. kontroler. Nie jest pozbawiona wad. Metoda ta, rozpoznaje wstrzyknięte zależności po nazwie co ogranicza programistów w nadawaniu nazw. Kolejność podawanych parametrów nie ma znaczenia.

W tej metodzie występuje również minifikacja. To proces usunięcia niepotrzebnych znaków, zdarza się, iż argumenty funkcji mają zmieniane nazwy, co powoduje wystąpienie błędu.

Przykład wstrzykiwania zależności

app.controller("appCtrl", function ($rootScope, $scope) { $scope.name = "Aplikacja 4"; console.log($rootScope.$$childHead.name) console.log($scope.name) })

Jak widzimy, dzięki $rootScope możemy się odwołać do konkretnego obiektu $scope.

Explicit Annotation

Sposób ten jest bardzo podobny do omówionego wyżej. Jednak kluczową różnicą jest tablica zawierająca wstrzyknięte zależności oraz jako ostatni element tablicy funkcję wykonującą. Kolejność umieszczanych parametrów w funkcji tym razem ma znaczenie, musi odpowiadać kolejności elementów w tablicy, jednakże nazwy parametrów mogą się różnić od elementów tablicy.

Przykład wstrzykiwania zależności

app.controller("appCtrl", ['$rootScope', '$scope', function ($rootScope, $scope) { $scope.name = "Aplikacja 4"; console.log($rootScope.$$childHead.name) console.log($scope.name) }])

Gdybyśmy zamienili parametry kolejnością, to w funkcji odwoływalibyśmy się do $rootScope dzięki parametru $scope, a do $scope dzięki parametru $rootScope.

Usługa $injector

Ostatnią metodą wstrzykiwania zależności jest wykorzystanie usługi $injector. Kolejność musi być taka sama dla usługi jak i dla parametrów funkcji wykonującej. Nazwy parametrów mogą być dowolne.

Przykład wstrzykiwania zależności

var appCtrl = function ($rootScope, $scope) { $scope.name = "Aplikacja 4"; console.log($rootScope.$$childHead.name) console.log($scope.name) } appCtrl.$injector = ['$rootScope', '$scope']; app.controller("appCtrl", appCtrl)

Wstrzykiwane obiekty

AngularJS pozwala nam na wstrzykiwanie obiektów takich jak:

  • Value
  • Factory
  • Service
  • Provider
  • Constant

Przykładowa aplikacja

<!DOCTYPE html> <html lang="pl" ng-app="app"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>AngularJS #4</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> </head> <body ng-controller="appCtrl"> <h1>{{name}}</h1> <script src="https://code.jquery.com/jquery-3.2.1.slim.js" integrity="sha256-tA8y0XqiwnpwmOIl3SGAcFl2RvxHjA8qp0+1uCGmRmg=" crossorigin="anonymous"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js"></script> <script> var app = angular.module("app", []); app.controller("appCtrl", function ($rootScope, $scope) { $scope.name = "Aplikacja 4"; console.log($rootScope.$$childHead.name) console.log($scope.name) }) app.controller("appCtrl", ['$rootScope', '$scope', function ($rootScope, $scope) { $scope.name = "Aplikacja 4"; console.log($rootScope.$$childHead.name) console.log($scope.name) }]) var appCtrl = function ($rootScope, $scope) { $scope.name = "Aplikacja 4"; console.log($rootScope.$$childHead.name) console.log($scope.name) } appCtrl.$injector = ['$rootScope', '$scope']; app.controller("appCtrl", appCtrl) </script> </body> </html>

Podsumowanie

Wstrzykiwanie zależność to jedna z ważniejszych rzeczy w AngularJS. Dzięki tej technice mamy większą kontrolę nad pisanym kodem. Z tego wpisu dowiedzieliśmy się, iż mamy trzy rodzaje dostępu do obiektów, jednak wstrzykiwanie z tych wszystkich jest najlepszą praktyką. Mamy również trzy rodzaje dodawania zależności. Osobiście najczęściej wykorzystuję, metodę przedstawioną jako ostatnią.

Pozdrawiam,
sirmarbug

Idź do oryginalnego materiału