Co to są „dekoratorzy” i jak się ich używa?

148

Jestem ciekaw, czym dokładnie są dekoratorzy w AngularJS. W Internecie nie ma zbyt wielu informacji dla dekoratorów, z wyjątkiem notki w dokumentacji AngularJS i krótkiej (choć interesującej) wzmianki w wideo na YouTube .

Jak to ujęli faceci z Angular, dekoratorem jest:

Dekoracja usługi, pozwala dekoratorowi przechwycić tworzenie instancji usługi. Zwrócone wystąpienie może być oryginalnym wystąpieniem lub nowym wystąpieniem, które jest delegowane do oryginalnego wystąpienia.

Naprawdę nie wiem, co to oznacza , i nie jestem pewien, dlaczego miałbyś oddzielić tę logikę od samej usługi. Na przykład, gdybym chciał zwrócić coś innego w różnych warunkach, po prostu przekazałbym różne argumenty do odpowiednich funkcji lub użył innej funkcji współdzielącej ten stan prywatny.

Nadal jestem noobem z AngularJS, więc jestem pewien, że to po prostu ignorancja i / lub złe nawyki, które wyłowiłem.

Kevin Beal
źródło

Odpowiedzi:

219

Dobrym przypadkiem użycia $provide.decoratorjest sytuacja, gdy musisz wykonać drobne „poprawki” w jakiejś usłudze zewnętrznej / nadrzędnej, od której zależy twój moduł, pozostawiając usługę nienaruszoną (ponieważ nie jesteś właścicielem / opiekunem usługi). Oto demonstracja na plunkr.

tamakisquare
źródło
6
Świetny przykład. Właściwie zastanawiałem się, jak rozszerzyć funkcjonalność modułów firm trzecich bez wtrącania się w nie
Arthur Kovacs
5
Czy dekoratorzy faktycznie dukktypują wszystkie wystąpienia usługi, czy też ograniczają się tylko do modułu, który je zdobi? Innymi słowy, powiedzmy, że mam moduł A, który zdobi usługę z modułu B. Mam wtedy moduł C, który zależy od modułu A i modułu B. Czy wewnątrz modułu C usługa z modułu B jest wersją oryginalną czy ozdobioną?
Jon Jaques
3
@JonJaques - To świetne pytanie. Nie spotkałem się z taką sytuacją. Gdybym miał zgadywać, wersja usługi, którą widzi moduł C, powinna być wersją ozdobioną z modułu A, ale nie mogę tego powiedzieć na pewno, dopóki sam tego nie wypróbuję. Może napiszesz prosty plik plunkr / jsffidle i poeksperymentujesz z tym. Byłoby wspaniale, gdybyś mógł podzielić się z nami swoim odkryciem. Twoje zdrowie.
tamakisquare
6
@JonJaques - Nie mogłem powstrzymać ciekawości, więc dodałem kilka wierszy do mojego oryginalnego przykładu, aby znaleźć odpowiedź na twoje pytanie, link . Krótko mówiąc, przypuszczenie z mojego poprzedniego komentarza jest słuszne.
tamakisquare
17
Fabryki, usługi itp. Są singletonami (tak jak są dostarczane), więc raz udekorowane, zawsze udekorowane.
FlavorScape
66

Dekoratorzy pozwalają nam oddzielić kwestie przekrojowe i pozwalają usługom zachować zasadę pojedynczej odpowiedzialności bez martwienia się o kod „infrastruktury”.

Praktyczne zastosowania dekoratorów:

  • Buforowanie: jeśli mamy usługę, która wykonuje potencjalnie kosztowne wywołania HTTP, możemy umieścić ją w dekoratorze buforującym, który sprawdza lokalną pamięć przed wykonaniem wywołania zewnętrznego.
  • Debugowanie / śledzenie: użyj przełącznika w zależności od konfiguracji programistycznej / produkcyjnej, który ozdabia Twoje usługi opakowaniami do debugowania lub śledzenia.
  • Ograniczanie: zawijanie często wyzwalanych wywołań w otoku usuwającym. Umożliwia nam na przykład łatwą interakcję z usługami o ograniczonej cenie.

We wszystkich tych przypadkach ograniczamy kod w serwisie do jego głównej odpowiedzialności.

JBland
źródło
10

decoratormoże przechwycić instancję usługi utworzoną przez factory, service, value, provideri daje opcje zmiany niektórych, instance(service)których w innym przypadku nie można skonfigurować / z opcjami.

Może również udostępniać przykładowe instancje do celów testowych, na przykład $http.

Daiwei
źródło
1
Warto dodać, że można również przesłonić directivedefinicje przedstawione przez Bena Nadela
Davida Salamona.
Oto odniesienie w oficjalnych dokumentach Angular: https://docs.angularjs.org/guide/decorators
David Salamon,
3

Krótko mówiąc, można powiedzieć, że jest to metoda rozszerzająca. Dla Ex. Mamy klasę, która ma dwie metody, aw czasie wykonywania chcemy dodać do niej więcej metod, a następnie używamy dekoratora.

Nie możemy użyć zmiennej $ provider.decorator ze stałymi, ponieważ nie możemy zmienić stałych, które mają, jako właściwość tylko do odczytu.

Gurupreet
źródło
1

W skrócie dekoratorów można opisać następująco: -

Funkcja dekoratora przechwytuje tworzenie usługi, umożliwiając zastąpienie lub zmodyfikowanie zachowania usługi.

Korzysta z $provideusługi w sposób kątowy i modyfikuje lub zastępuje implementację innej usługi

$provide.decorator('service to decorate',['$delegate', function($delegate) {
  // $delegate - The original service instance, 
  //             which can be replaced, monkey patched, 
  //             configured, decorated or delegated to. 
  //             ie here what is there in the 'service to decorate'

  //   This function will be invoked, 
  //   when the service needs to be provided 
  //   and should return the decorated service instance.
  return $delegate;
}]);

Przykład:

$provide.decorator('$log', ['$delegate', function($delegate) {
  // This will change implementation of log.war to log.error
  $delegate.warn = $delegate.error; 
  return $delegate;
}]);

Aplikacje

Oprócz odpowiedzi @JBland.

  • Ustawienia regionalne aplikacji: -

    Można znaleźć przykład tutaj

  • Zmiana domyślnego zachowania i istniejącej implementacji usługi przez usługę kątową: -

    Możesz znaleźć przykład tutaj

  • Przełączanie funkcji w różnych środowiskach.

samuelj90
źródło