Jak rozumiem, w fabryce zwracam przedmiot, który zostaje wstrzyknięty do kontrolera. W usłudze mam do czynienia z obiektem, this
który niczego nie zwraca i nie zwraca.
Zakładałem, że usługa zawsze była singletonem i że do każdego sterownika wstrzykiwany jest nowy obiekt fabryczny . Jak się jednak okazuje, obiekt fabryczny też jest singletonem?
Przykładowy kod do zademonstrowania:
var factories = angular.module('app.factories', []);
var app = angular.module('app', ['ngResource', 'app.factories']);
factories.factory('User', function () {
return {
first: 'John',
last: 'Doe'
};
});
app.controller('ACtrl', function($scope, User) {
$scope.user = User;
});
app.controller('BCtrl', function($scope, User) {
$scope.user = User;
});
Po zmianie user.first
w ACtrl
Okazuje się, że user.first
w BCtrl
jest również zmienione, np User
jest pojedyncza?
Moje założenie było takie, że nowa instancja została wstrzyknięta do kontrolera z fabryką?
Odpowiedzi:
Wszystkie usługi kątowe są singletonami :
Dokumenty (patrz Usługi jako singletony ): https://docs.angularjs.org/guide/services
Zasadniczo różnica między usługą a fabryką jest następująca:
Sprawdź tę prezentację na temat $ zapewniają: http://slides.wesalvaro.com/20121113/#/
Te slajdy zostały użyte podczas jednego ze spotkań AngularJs: http://blog.angularjs.org/2012/11/more-angularjs-meetup-videos.html
źródło
new
tego.Dla mnie objawienie pojawiło się, gdy zdałem sobie sprawę, że wszystkie działają w ten sam sposób: uruchamiając coś raz , przechowując otrzymaną wartość, a następnie odkrztuszając tę samą przechowywaną wartość, gdy odwołuje się do niej poprzez Dependency Injection.
Powiedzmy, że mamy:
Różnica między tymi trzema polega na tym, że:
a
przechowywana wartość pochodzi z działaniafn
, innymi słowy:fn()
b
przechowywana wartość pochodzi znew
ingfn
, innymi słowy:new fn()
c
Zapisana wartość pochodzi z pierwszego pobrania instancji przeznew
ingfn
, a następnie uruchomienia$get
metody instancjico oznacza, że wewnątrz kąta znajduje się coś w rodzaju obiektu pamięci podręcznej, którego wartość każdego zastrzyku jest przypisywana tylko raz, gdy zostały wstrzyknięte po raz pierwszy i gdzie:
Dlatego używamy
this
w usługach i definiujemythis.$get
dostawców.Mam nadzieję że to pomoże.
źródło
przykład na żywo
przykład „witaj świecie”
z
factory
/service
/provider
:źródło
Istnieje również sposób na zwrócenie funkcji konstruktora, dzięki czemu można zwrócić klasy neible w fabrykach, takie jak to:
Możesz to zrobić w kontrolerze, który używa MyObjectWithParam:
Zobacz tutaj pełny przykład:
http://plnkr.co/edit/GKnhIN?p=preview
A tutaj strony grupy google, na których omawiano:
https://groups.google.com/forum/#!msg/angular/56sdORWEoqg/b8hdPskxZXsJ
źródło
App.factory('MyObjectWithParam', ['$injector', function ($injector) { return function(name) { return $injector.instantiate(MyObjectWithParam,{ name: name }); }; }]);
Przeczytaj więcej na ten temat tutaj: docs.quarejs.org/tutorial/step_05.service
zamiast tego użyć ?.factory
w przeciwieństwie do.service
?new Car('BMW')
inew Car('Ford')
a oni nie mają tych samych zmiennych i wszystko.Oto podstawowe różnice:
Usługi
Składnia:
module.service( 'serviceName', function );
Wynik: deklarując serviceName jako argument do wstrzyknięcia, otrzymasz instancję funkcji przekazanej do
module.service
.Użycie: Może być przydatny do udostępniania funkcji narzędziowych, które można wywołać, po prostu dodając () do wstrzykniętego odwołania do funkcji. Można go również uruchomić z
injectedArg.call( this )
podobnym.Fabryki
Składnia:
module.factory( 'factoryName', function );
Wynik: deklarując nazwę fabryki jako argument do wstrzyknięcia, otrzymasz wartość zwracaną przez wywołanie przekazanego odwołania do funkcji
module.factory
.Użycie: Może być przydatny do zwracania funkcji „klasy”, którą można następnie zmienić w celu utworzenia instancji.
Sprawdź także dokumentację AngularJS i podobne pytanie na temat przepełnienia stosu, mylone co do usługi kontra fabryka .
Oto przykład korzystania z usług i fabryki . Przeczytaj więcej o usłudze AngularJS vs fabryka .
źródło
Dodając do pierwszej odpowiedzi, myślę, że .service () jest dla ludzi, którzy napisali swój kod w stylu bardziej obiektowym (C # / Java) (używając tego słowa kluczowego i instancji obiektu za pomocą funkcji prototypu / konstruktora).
Fabryka przeznaczona jest dla programistów, którzy piszą kod bardziej naturalny dla javascript / funkcjonalnego stylu kodowania.
Spójrz na kod źródłowy .service i .factory metody wewnątrz angular.js - wewnętrznie wszystkie one wywołują metodę dostawcy:
źródło
Bardzo prosto:
.service - zarejestrowana funkcja zostanie wywołana jako konstruktor (alias „newed”)
.factory - zarejestrowana funkcja zostanie wywołana jako funkcja prosta
Oba są wywoływane raz, co powoduje powstanie obiektu singleton, który zostaje wstrzyknięty do innych składników aplikacji.
źródło
Wszyscy dostawcy działają w ten sam sposób. Różne metody
service
,factory
,provider
tylko pozwalają osiągnąć to samo w mniej kodu.PS Jest też
value
iconstant
.Każdy specjalny przypadek w dół łańcucha, zaczynający się
provider
i kończący na,value
ma dodatkowe ograniczenie. Aby więc zdecydować między nimi, musisz zadać sobie pytanie, co pozwoli ci osiągnąć to, czego chcesz, przy mniejszym kodowaniu.Oto zdjęcie, które pokazuje, co mam na myśli:
Możesz podzielić przewodnik i przewodnik referencyjny na blogu, który dostałem ten obraz z:
http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory-in-angularjs/
źródło
console.log()
i wstrzykiwanie do wielu kontrolerów.Oto kilka innych przykładów usług w porównaniu z fabrykami, które mogą być przydatne w dostrzeżeniu różnicy między nimi. Zasadniczo usługa wywołała „nowe ...”, jest już utworzona. Fabryka nie jest tworzona automatycznie.
Podstawowe przykłady
Zwraca obiekt klasy, który ma jedną metodę
Oto usługa, która ma jedną metodę:
Oto fabryka, która zwraca obiekt za pomocą metody:
Zwróć wartość
Fabryka, która zwraca listę liczb:
Usługa, która zwraca listę liczb:
Dane wyjściowe w obu przypadkach są takie same, lista liczb.
Zaawansowane przykłady
Zmienne „klasy” wykorzystujące fabryki
W tym przykładzie definiujemy CounterFactory, który zwiększa lub zmniejsza licznik i możesz uzyskać bieżącą liczbę lub liczbę obiektów CounterFactory, które zostały utworzone:
Używamy
CounterFactory
do tworzenia wielu liczników. Możemy uzyskać dostęp do zmiennej klasy, aby zobaczyć, ile liczników zostało utworzonych:Dane wyjściowe tego kodu to:
źródło
„Fabryka” i „Serwis” to różne sposoby wykonywania DI (wstrzykiwanie zależności) pod kątem.
Kiedy więc definiujemy DI za pomocą „usługi”, jak pokazano w poniższym kodzie. To tworzy nową GLOBALNĄ instancję obiektu „Logger” i wstrzykuje ją do funkcji.
Kiedy definiujesz DI za pomocą „fabryki”, nie tworzy instancji. Po prostu przechodzi tę metodę, a później konsument musi wewnętrznie wykonywać połączenia z fabryką dla instancji obiektów.
Poniżej znajduje się prosty obraz, który pokazuje wizualnie, w jaki sposób proces DI dla „Usługi” różni się od „Fabryki”.
Fabryka powinna być używana, gdy chcemy tworzyć różne typy obiektów w zależności od scenariuszy. Na przykład w zależności od scenariusza chcemy utworzyć prosty obiekt „Klient” lub „Klient” z obiektem „Adres” lub „Klient” z obiektem „Telefon”. Oto szczegółowe wyjaśnienie tego akapitu
Z usługi należy korzystać, gdy mamy do dyspozycji zastrzyk narzędzi lub funkcji wspólnych, takich jak Narzędzie, Rejestrator, Obsługa błędów itp.
źródło
Styl usługi : ( prawdopodobnie najprostszy ) zwraca rzeczywistą funkcję: Przydatny do współdzielenia funkcji narzędziowych, które można wywołać, po prostu dodając () do wstrzykniętego odwołania do funkcji.
Usługa w AngularJS to pojedynczy obiekt JavaScript, który zawiera zestaw funkcji
Styl fabryczny : ( bardziej zaangażowany, ale bardziej wyrafinowany ) zwraca wartość zwracaną przez funkcję: tworzy obiekt w stylu jak nowy obiekt () w java.
Fabryka to funkcja tworząca wartości. Gdy usługa, sterownik itp. Potrzebuje wartości wprowadzonej z fabryki, fabryka tworzy wartość na żądanie. Po utworzeniu wartość jest ponownie wykorzystywana dla wszystkich usług, kontrolerów itp., Które wymagają jej wstrzyknięcia.
Styl dostawcy : ( pełna wersja, konfigurowalna wersja ) zwraca wynik funkcji $ get function: Configurable.
Dostawcy w AngularJS to najbardziej elastyczna forma fabryki, jaką możesz stworzyć. Rejestrujesz dostawcę w module tak, jak robisz to w usłudze lub fabryce, tyle że zamiast tego używasz funkcji dostawca ().
src jenkov
jsbin
jsfiddle
źródło
Podstawowa różnica polega na tym, że dostawca pozwala na ustawienie prymitywnych (niebędących obiektami), tablicowych lub funkcji zwrotnych wartości w fabrycznie zadeklarowanej zmiennej, a zatem jeśli zwraca obiekt, musi być jawnie zadeklarowany i zwrócony.
Z drugiej strony usługi można użyć tylko do ustawienia zmiennej zadeklarowanej dla obiektu na obiekt, dzięki czemu możemy uniknąć jawnego tworzenia i zwracania obiektów, z drugiej strony pozwala to na użycie tego słowa kluczowego.
Lub w skrócie: „ dostawca jest bardziej ogólną formą, podczas gdy usługa jest ograniczona tylko do obiektów”.
źródło
W ten sposób zrozumiałem różnicę między nimi pod względem wzorców projektowych:
Usługa : zwraca typ, który zostanie dodany w celu utworzenia obiektu tego typu. Jeśli używana jest analogia Java, usługa zwraca definicję klasy Java .
Fabryka : zwraca konkretny obiekt, z którego można natychmiast skorzystać. W analogii Java fabryka zwraca obiekt Java .
Część, która często myli ludzi (w tym mnie), polega na tym, że kiedy wstrzykujesz do kodu usługę lub fabrykę, można z nich korzystać w ten sam sposób, co dostajesz w kodzie w obu przypadkach, jest konkretnym obiektem, który możesz natychmiast wywołać. Co oznacza, że w przypadku Usługi połączenia kątowe są „nowe” w deklaracji usługi w Twoim imieniu. Myślę, że to zawiła koncepcja.
źródło
To byłaby najlepsza i krótka odpowiedź na zrozumienie dostawcy Vs Factory Vs Provider
Źródło : https://groups.google.com/forum/#!msg/angular/56sdORWEoqg/HuZsOsMvKv4J
Oto, co mówi Ben z demo http://jsbin.com/ohamub/1/edit?html,output
„W kodzie znajdują się komentarze ilustrujące podstawowe różnice, ale tutaj trochę je rozwinę. Uwaga: po prostu zastanawiam się nad tym, więc jeśli powiem coś złego, daj mi znać.
Usługi
Składnia : module.service ('serviceName', funkcja);
Wynik : deklarując serviceName jako argument do wstrzyknięcia, otrzymasz rzeczywiste odwołanie do funkcji przekazane do module.service.
Użycie : Może być przydatny do udostępniania funkcji narzędziowych, które można wywołać, po prostu dodając () do wstrzykniętego odwołania do funkcji. Można go również uruchomić za pomocą injectedArg.call (this) lub podobnego.
Fabryki
Składnia : module.factory ('nazwa_fabryki', funkcja);
Wynik : deklarując nazwę fabryczną jako argument do wstrzyknięcia, otrzymasz wartość zwracaną przez wywołanie odwołania do funkcji przekazanego do module.factory.
Użycie : Może być przydatny do zwracania funkcji „klasy”, którą można następnie zmienić w celu utworzenia instancji.
Dostawcy
Składnia : module.provider ('dostawcaName', funkcja);
Wynik : deklarując nazwę dostawcy jako argument do wstrzyknięcia, otrzymasz wartość zwracaną przez wywołanie metody $ get odwołania do funkcji przekazanej do module.provider.
Użycie : Może być przydatny do zwracania funkcji „klasy”, którą można następnie zmienić w celu utworzenia instancji, ale która wymaga pewnej konfiguracji przed wstrzyknięciem. Być może przydatne w przypadku klas, które można wielokrotnie wykorzystywać w różnych projektach? Wciąż trochę niejasno w tej sprawie. ”Ben
źródło
Przez jakiś czas miałem to zamieszanie i staram się jak najlepiej wyjaśnić tutaj. Mam nadzieję, że to pomoże!
angular .factory
iangular .service
oba służą do inicjalizacji usługi i pracy w ten sam sposób.Jedyna różnica polega na tym, jak chcesz zainicjować usługę.
Oba są singletonami
Fabryka
app.factory (
<service name>
,<function with a return value>
)Jeśli chcesz zainicjować usługę z funkcji, którą masz z wartością zwracaną , musisz użyć tej
factory
metody.na przykład
Podczas wstrzykiwania tej usługi (np. Do kontrolera):
myService()
), aby powrócić obiektuUsługa
app.service (
<service name>
,<constructor function>
)Jeśli chcesz zainicjować usługę z funkcji konstruktora (używając
this
słowa kluczowego), musisz użyć tejservice
metody.na przykład
Podczas wstrzykiwania tej usługi (np. Do kontrolera):
new
podaną funkcję (asnew myService()
), aby zwrócić obiektUWAGA: Jeśli używasz
factory
z<constructor function>
lubservice
z<function with a return value>
, to nie będzie działać.Przykłady - DEMO
źródło
To pomogło mi zrozumieć różnicę dzięki postowi na blogu Pascala Prechta.
Usługa to metoda w module, która przyjmuje nazwę i funkcję, która definiuje usługę. Możesz wstrzykiwać i używać tej konkretnej usługi w innych komponentach, takich jak kontrolery, dyrektywy i filtry. Fabryka jest metodą na module, a także wymaga nazwy i funkcji, która definiuje fabrykę. Możemy również wstrzykiwać i używać go w taki sam sposób, jak w przypadku usługi.
Obiekty utworzone przy użyciu nowego używają wartości właściwości prototypowej funkcji konstruktora jako ich prototypu, więc znalazłem kod Angular, który wywołuje Object.create (), który moim zdaniem jest funkcją konstruktora usług, gdy zostanie utworzona instancja. Jednak funkcja fabryczna jest tak naprawdę tylko funkcją, która jest wywoływana, dlatego musimy zwrócić literał obiektu dla fabryki.
Oto kod kątowy 1.5, który znalazłem dla fabryki:
Kątowy fragment kodu źródłowego dla funkcji factory ():
Pobiera przekazaną nazwę i funkcję fabryczną i zwraca dostawcę o tej samej nazwie, który ma metodę $ get, która jest naszą funkcją fabryczną. Ilekroć pytasz wtryskiwacza o konkretną zależność, w zasadzie pyta on odpowiedniego dostawcę o instancję tej usługi, wywołując metodę $ get (). Dlatego $ get () jest wymagany podczas tworzenia dostawców.
Oto kątowy kod 1.5 dla usługi.
Okazuje się, że kiedy wywołujemy service (), tak naprawdę wywołuje factory ()! Jednak nie tylko przekazuje fabryczną funkcję konstruktora usług. Przekazuje także funkcję, która prosi wtryskiwacz o utworzenie obiektu przez dany konstruktor.
Innymi słowy, jeśli wstrzykniemy gdzieś MyService, to co dzieje się w kodzie to:
Aby ponownie utworzyć go ponownie, usługa wywołuje fabrykę, która jest metodą $ get () na odpowiednim dostawcy. Ponadto $ injector.instantiate () jest metodą, która ostatecznie wywołuje Object.create () z funkcją konstruktora. Dlatego używamy „tego” w usługach.
W przypadku ES5 nie ma znaczenia, z którego korzystamy: service () lub factory (), zawsze jest wywoływana fabryka, która tworzy dostawcę naszych usług.
Możesz zrobić dokładnie to samo z usługami. Usługa jest jednak funkcją konstruktora, która nie uniemożliwia nam zwracania literałów obiektowych. Abyśmy mogli pobrać nasz kod serwisowy i napisać go w taki sposób, że zasadniczo robi dokładnie to samo, co nasza fabryka, lub innymi słowy, możesz napisać usługę jako fabryka, aby zwrócić obiekt.
Dlaczego większość ludzi zaleca korzystanie z fabryk zamiast usług? To najlepsza odpowiedź, jaką widziałem, pochodząca z książki Pawła Kozłowskiego: Mastering Web Application Development with AngularJS.
źródło
this
słowa kluczowego do zdefiniowania funkcji.$get
zdefiniowany przez Ciebie obiekt, który można wykorzystać do uzyskania obiektu, który zwraca dane.źródło
Istnieją trzy sposoby obsługi logiki biznesowej w AngularJS: ( zainspirowane kursem Yaakova Coursera AngularJS ):
Tutaj będziemy rozmawiać tylko o usłudze vs fabryka
SERWIS :
Składnia:
app.js
index.html
Główne cechy Usługi:
Instancja Lazily : jeśli usługa nie zostanie wstrzyknięta, nigdy nie zostanie utworzona. Aby go użyć, musisz wstrzyknąć go do modułu.
Singleton : Jeśli zostanie wstrzyknięty do wielu modułów, wszystkie będą miały dostęp tylko do jednego konkretnego wystąpienia. Dlatego bardzo wygodne jest udostępnianie danych między różnymi kontrolerami.
FABRYKA
Porozmawiajmy teraz o fabryce w AngularJS
Najpierw spójrzmy na składnię :
app.js :
Teraz używając dwóch powyższych w kontrolerze:
Funkcje fabryki:
Tego rodzaju usługi są zgodne z fabrycznym wzorcem projektowym . Fabrykę można traktować jako centralne miejsce, w którym tworzone są nowe obiekty lub metody.
To nie tylko produkuje singleton, ale także dostosowywane usługi.
.service()
Metoda jest fabryka , która zawsze daje ten sam rodzaj usługi, która jest pojedyncza. Nie ma łatwego sposobu skonfigurowania jego zachowania. Ta.service()
metoda jest zwykle używana jako skrót do czegoś, co nie wymaga żadnej konfiguracji.źródło
Krótkie i proste wyjaśnienia znajdują się na stronie https://stackoverflow.com/a/26924234/5811973 .
Aby uzyskać szczegółowe wyjaśnienia, patrz https://stackoverflow.com/a/15666049/5811973 .
Również z dokumentacji angularJs:
źródło
Z tą analogią możesz zrozumieć różnicę - rozważ różnicę między funkcją normalną, która zwróci pewną wartość, a funkcją konstruktora, która zostanie utworzona za pomocą nowego słowa kluczowego. Tak więc tworzenie fabryki jest podobne do tworzenia normalnej funkcji, która zwróci pewną wartość (prymitywne lub obiekt), podczas gdy tworzenie usługi przypomina tworzenie funkcji konstruktora (klasa OO), dla której możemy utworzyć instancję za pomocą nowego słowa kluczowego. Jedyną rzeczą, na którą należy zwrócić uwagę, jest to, że kiedy używamy metody Service do tworzenia usług, automatycznie tworzy jej instancję za pomocą mechanizmu wstrzykiwania zależności obsługiwanego przez AngularJS
źródło