kanciaste.serwis vs angular.fabryka

Widziałem oba kątowe.factory () i service () używane do deklarowania Usług; jednak I nie może znaleźć angular.service gdziekolwiek w oficjalnej dokumentacji.

Jaka jest różnica między tymi dwoma metodami? Które powinny być używane do czego (zakładając, że robią różne rzeczy)?

Author: Gil Birman, 2013-01-14

9 answers

  angular.service('myService', myServiceFunction);
  angular.factory('myFactory', myFactoryFunction);

Miałem problem z tym pojęciem, dopóki nie ująłem tego w ten sposób:

Service : funkcja którą napiszesz będzie new -ed:

  myInjectedService  <----  new myServiceFunction()

Factory : funkcja (constructor) którą napiszesz będzie wywoływana :

  myInjectedFactory  <---  myFactoryFunction()
To, co z tym zrobisz, zależy od ciebie, ale jest kilka przydatnych wzorców...

, np. napisanie usługi funkcji do ujawnienia a public API:

function myServiceFunction() {
  this.awesomeApi = function(optional) {
    // calculate some stuff
    return awesomeListOfValues;
  }
}
---------------------------------------------------------------------------------
// Injected in your controller
$scope.awesome = myInjectedService.awesomeApi();
W przeciwieństwie do poprzednich wersji, API nie jest w pełni kompatybilne z API.]}
function myFactoryFunction() {
  var aPrivateVariable = "yay";

  function hello() {
    return "hello mars " + aPrivateVariable;
  }

  // expose a public API
  return {
    hello: hello
  };
}
---------------------------------------------------------------------------------
// Injected in your controller
$scope.hello = myInjectedFactory.hello();
W tym celu należy użyć funkcji factory, która zwróci konstruktor:
function myFactoryFunction() {
    return function() {
        var a = 2;
        this.a2 = function() {
            return a*2;
        };
    };
}
---------------------------------------------------------------------------------
// Injected in your controller
var myShinyNewObject = new myInjectedFactory();
$scope.four = myShinyNewObject.a2();

Którego użyć?...

Możesz osiągnąć to samo z obydwoma. Jednak w niektórych przypadkach fabryka daje Ci trochę więcej elastyczności w tworzeniu iniekcji o prostszej składni. To dlatego, że podczas gdy myInjectedService zawsze musi być obiektem, myInjectedFactory może być obiektem, odniesieniem do funkcji lub dowolną wartością. Na przykład, jeśli napisałeś usługę do tworzenia konstruktora( jak w poprzednim przykładzie powyżej), musiałby być utworzony w taki sposób:

var myShinyNewObject = new myInjectedService.myFunction()

Co jest prawdopodobnie mniej pożądane niż to:

var myShinyNewObject = new myInjectedFactory();

(ale powinieneś uważać na używanie tego typu wzorców, ponieważ nowe obiekty-ING w kontrolerach tworzą trudne do śledzenia zależności, które są trudne do wyśledzenia testuję. Lepiej mieć usługę zarządzającą kolekcją obiektów za ciebie niż używać new() sprytnie.)


Jeszcze jedno, wszystkie są Singletonami...

Należy również pamiętać, że w obu przypadkach angular pomaga w zarządzaniu singletonem. Niezależnie od tego, gdzie i ile razy wstrzykniesz usługę lub funkcję, otrzymasz to samo odniesienie do tego samego obiektu lub funkcji. (Z wyjątkiem sytuacji, gdy fabryka po prostu zwraca wartość taką jak liczba lub łańcuch znaków. W takim razie, zawsze otrzymasz tę samą wartość, ale nie referencję.)

 1252
Author: Gil Birman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-27 20:58:17

Po prostu ..

// Service
service = (a, b) => {
  a.lastName = b;
  return a;
};

// Factory
factory = (a, b) => Object.assign({}, a, { lastName: b });

const fullName = { firstName: 'john' };

// Service
const lastNameService = (a, b) => {
  a.lastName = b;
  return a;
};
console.log(lastNameService(fullName, 'doe'));

// Factory
const lastNameFactory = (a, b) => 
  Object.assign({}, a, { lastName: b })
console.log(lastNameFactory(fullName, 'doe'));
 316
Author: Kirk Strobeck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-05 20:07:27

Oto podstawowe różnice:

Usługi

Składnia: module.service( 'serviceName', function );

Wynik: deklarując serviceName jako argument iniekcyjny, otrzymasz instancję funkcji przekazaną do module.service.

Użycie: może być użyteczne dla dzielenia funkcji użytkowych , które są użyteczne do wywołania przez zwykłe dołączenie ( ) do iniekcyjnego odniesienia do funkcji. Może być również uruchamiany z injectedArg.call( this ) lub podobnym.

Fabryki

Składnia: module.factory( 'factoryName', function );

Wynik: podczas deklarowania factoryName jako argumentu iniekcyjnego otrzymasz wartość , która jest zwracana przez wywołanie referencji funkcji przekazanej do module.factory.

Użycie: może być przydatne do zwracania 'class' funkcji, która może być następnie nowa w celu utworzenia instancji.

Oto przykład korzystania z usług i fabryki. Przeczytaj więcej o AngularJS Service vs Factory .

Możesz również sprawdzić AngularJS dokumentacja i podobne pytanie na temat stackoverflow mylone o serwis vs fabryka.

 244
Author: Manish Chhabra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:47

TL; DR

1) gdy używasz fabryki , tworzysz obiekt, dodajesz do niego właściwości, a następnie zwracasz ten sam obiekt. Po przeniesieniu tej fabryki do kontrolera, te właściwości obiektu będą teraz dostępne w tym kontrolerze za pośrednictwem fabryki.

app.controller('myFactoryCtrl', function($scope, myFactory){
  $scope.artist = myFactory.getArtist();
});

app.factory('myFactory', function(){
  var _artist = 'Shakira';
  var service = {};

  service.getArtist = function(){
    return _artist;
  }

  return service;
});


2) Gdy używasz usługi , Angular tworzy ją za kulisami za pomocą słowa kluczowego "new". Dzięki temu dodasz właściwości do "to" i służba zwróci "to". Po przekazaniu usługi do kontrolera, te właściwości na "to" będą teraz dostępne w tym kontrolerze za pośrednictwem usługi.

app.controller('myServiceCtrl', function($scope, myService){
  $scope.artist = myService.getArtist();
});

app.service('myService', function(){
  var _artist = 'Nelly';
  this.getArtist = function(){
    return _artist;
  }
});



Non TL; DR

1) Fabryka
Fabryki są najpopularniejszym sposobem tworzenia i konfigurowania usługi. Naprawdę nie ma wiele więcej niż to, co TL;DR powiedział. Po prostu tworzysz obiekt, dodajesz do niego właściwości, a następnie zwracasz ten sam obiekt. Następnie, po przeniesieniu fabryki do kontrolera, te właściwości obiektu będą teraz dostępne w tym kontrolerze za pośrednictwem fabryki. Bardziej rozbudowany przykład znajduje się poniżej.

app.factory('myFactory', function(){
  var service = {};
  return service;
});

Teraz wszystkie właściwości, które dołączamy do "usługi", będą dla nas dostępne, gdy przekażemy "myFactory" do naszego kontrolera.

Teraz dodajmy kilka' prywatnych ' zmiennych do naszej funkcji zwrotnej. Nie będą one dostępne bezpośrednio z kontrolera, ale ostatecznie skonfigurujemy kilka metody getter / setter na 'service', aby móc zmieniać te' prywatne ' zmienne w razie potrzeby.

app.factory('myFactory', function($http, $q){
  var service = {};
  var baseUrl = 'https://itunes.apple.com/search?term=';
  var _artist = '';
  var _finalUrl = '';

  var makeUrl = function(){
   _artist = _artist.split(' ').join('+');
    _finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK';
    return _finalUrl
  }

  return service;
});

Tutaj zauważysz, że nie dołączamy tych zmiennych / funkcji do 'usługi'. Po prostu je tworzymy, aby później je wykorzystać lub zmodyfikować.

    BaseUrl jest bazowym adresem URL wymaganym przez API iTunes.]}
  • _artist jest artystą, którego chcemy szukać
  • _finalUrl jest finalnym i w pełni zbudowanym adresem URL, na który wykonamy połączenie do iTunes makeUrl jest funkcja, która stworzy i zwróci naszą przyjazny adres URL iTunes.

Teraz, gdy nasze helper / prywatne zmienne i funkcja są już na swoim miejscu, dodajmy kilka właściwości do obiektu 'service'. Niezależnie od tego, co umieścimy w "serwisie", będziemy mogli używać bezpośrednio w dowolnym kontrolerze, do którego podamy "myFactory".

Stworzymy metody setArtist i getArtist, które po prostu zwrócą lub ustawią artystę. Stworzymy również metodę, która wywoła API iTunes z naszego utworzonego URL. Ta metoda zwróci obietnicę, która zostanie spełniona, gdy dane powrócą z interfejsu API iTunes. Jeśli nie masz dużego doświadczenia w korzystaniu z obietnic w Angular, Gorąco polecam zrobienie na nich głębokiego nurkowania.

Poniżej setArtist akceptuje artystę i pozwala ustawić artystę. getArtist zwraca wykonawcę wywołującego wywołania makeUrl () w celu zbudowania adresu URL, którego użyjemy z żądaniem $http. Następnie ustawia obiekt promise, czyni $http request z naszym ostatecznym url, to ponieważ $http zwraca obietnicę, jesteśmy w stanie zadzwonić .sukces lub .błąd po naszej prośbie. Następnie rozwiązujemy naszą obietnicę za pomocą danych iTunes lub odrzucamy ją z Komunikatem "wystąpił błąd".

app.factory('myFactory', function($http, $q){
  var service = {};
  var baseUrl = 'https://itunes.apple.com/search?term=';
  var _artist = '';
  var _finalUrl = '';

  var makeUrl = function(){
    _artist = _artist.split(' ').join('+');
    _finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK'
    return _finalUrl;
  }

  service.setArtist = function(artist){
    _artist = artist;
  }

  service.getArtist = function(){
    return _artist;
  }

  service.callItunes = function(){
    makeUrl();
    var deferred = $q.defer();
    $http({
      method: 'JSONP',
      url: _finalUrl
    }).success(function(data){
      deferred.resolve(data);
    }).error(function(){
      deferred.reject('There was an error')
    })
    return deferred.promise;
  }

  return service;
});

Teraz nasza fabryka jest kompletna. Jesteśmy teraz w stanie wstrzyknąć 'myFactory' do dowolnego kontrolera, a następnie będziemy mogli wywołać nasze metody, które dołączyliśmy do naszego obiektu usługowego (setArtist, getArtist i callItunes).

app.controller('myFactoryCtrl', function($scope, myFactory){
  $scope.data = {};
  $scope.updateArtist = function(){
    myFactory.setArtist($scope.data.artist);
  };

  $scope.submitArtist = function(){
    myFactory.callItunes()
      .then(function(data){
        $scope.data.artistData = data;
      }, function(data){
        alert(data);
      })
  }
});

W kontroler powyżej wprowadzamy w usłudze "myFactory". Następnie ustawiamy właściwości naszego obiektu $ scope, które pochodzą z danych z 'myFactory'. Jedynym trudnym kodem powyżej jest, jeśli nigdy wcześniej nie miałeś do czynienia z obietnicami. Ponieważ callItunes zwraca obietnicę, jesteśmy w stanie użyć.następnie metoda () i ustaw tylko $scope.data.artistData po spełnieniu naszej obietnicy z danymi iTunes. Zauważysz, że nasz kontroler jest bardzo "cienki". Cała nasza logika i trwałe DANE znajdują się w naszym usługi, nie w naszym kontrolerze.

2) serwis
Być może największą rzeczą, o której warto wiedzieć, gdy mamy do czynienia z tworzeniem usługi, jest to, że jest ona inicjowana za pomocą słowa kluczowego "nowy". Dla Ciebie Guru JavaScript powinno to dać Ci dużą podpowiedź na temat natury kodu. Dla tych z was z ograniczonym doświadczeniem w JavaScript lub dla tych, którzy nie są zbyt zaznajomieni z tym, co faktycznie robi "nowe" słowo kluczowe, przejrzyjmy niektóre podstawy JavaScript, które w końcu nam pomogą w zrozumieniu charakteru usługi.

Aby naprawdę zobaczyć zmiany zachodzące podczas wywoływania funkcji słowem kluczowym 'new', stwórzmy funkcję i wywołajmy ją słowem kluczowym' new', a następnie pokażmy, co robi interpreter, gdy widzi słowo kluczowe' new'. Wyniki końcowe będą takie same.

Najpierw stwórzmy nasz Konstruktor.

var Person = function(name, age){
  this.name = name;
  this.age = age;
}

Jest to typowa funkcja konstruktora JavaScript. Teraz, gdy wywołujemy funkcję Person używając 'new' słowo kluczowe "this" będzie powiązane z nowo utworzonym obiektem.

Teraz dodajmy metodę do prototypu naszej osoby, aby była ona dostępna dla każdej instancji 'klasy' naszej osoby.

Person.prototype.sayName = function(){
  alert('My name is ' + this.name);
}

Teraz, ponieważ umieściliśmy funkcję sayName w prototypie, każda instancja osoby będzie mogła wywołać funkcję sayName w celu powiadomienia o nazwie tej instancji.

Teraz, gdy mamy funkcję Person constructor i funkcję sayName na swoim prototypie, właściwie Utwórz instancję osoby, a następnie wywołaj funkcję sayName.

var tyler = new Person('Tyler', 23);
tyler.sayName(); //alerts 'My name is Tyler'

Więc wszystkie razem kod do tworzenia konstruktora Person, dodawania funkcji do prototypu, tworzenia instancji Person, a następnie wywołania funkcji na prototypie wygląda tak.

var Person = function(name, age){
  this.name = name;
  this.age = age;
}
Person.prototype.sayName = function(){
  alert('My name is ' + this.name);
}
var tyler = new Person('Tyler', 23);
tyler.sayName(); //alerts 'My name is Tyler'

Przyjrzyjmy się teraz, co tak naprawdę dzieje się, gdy używasz słowa kluczowego 'new' w JavaScript. Pierwszą rzeczą, którą powinieneś zauważyć, jest to, że po użyciu 'new' w naszym przykładzie, jesteśmy w stanie wywołać metodę (sayName) na "tyler" tak, jakby to był przedmiot - to dlatego, że jest. Więc najpierw wiemy, że nasz Konstruktor Person zwraca obiekt, niezależnie od tego, czy widzimy to w kodzie, czy nie. Po drugie, wiemy, że ponieważ nasza funkcja sayName znajduje się na prototypie, a nie bezpośrednio na instancji Person, obiekt, który zwraca funkcja Person, musi być delegowany do swojego prototypu przy nieudanych wyszukiwaniach. Mówiąc prościej, kiedy nazwiemy Tylera.sayName () interpreter mówi: "OK, poszukam na obiekt' tyler', który właśnie stworzyliśmy, zlokalizuj funkcję sayName i wywołaj ją. Chwileczkę, nie widzę tego tutaj - widzę tylko imię i wiek, sprawdzę prototyp. Wygląda na to, że jest na prototypie.".

Poniżej znajduje się kod, w jaki sposób możesz myśleć o tym, co faktycznie robi słowo kluczowe "nowy" w JavaScript. Jest to w zasadzie przykład kodu z powyższego akapitu. Umieściłem 'interpreter view' lub sposób, w jaki interpreter widzi kod wewnątrz notatki.

var Person = function(name, age){
  //The line below this creates an obj object that will delegate to the person's prototype on failed lookups.
  //var obj = Object.create(Person.prototype);

  //The line directly below this sets 'this' to the newly created object
  //this = obj;

  this.name = name;
  this.age = age;

  //return this;
}

Teraz mając tę wiedzę o tym, co naprawdę robi słowo kluczowe "nowy" w JavaScript, Tworzenie usługi w Angular powinno być łatwiejsze do zrozumienia.

Największą rzeczą do zrozumienia podczas tworzenia usługi jest świadomość, że usługi są tworzone z użyciem słowa kluczowego 'new'. Łącząc tę wiedzę z naszymi powyższymi przykładami, powinieneś teraz rozpoznać, że będziesz dołączać swoje właściwości i metody bezpośrednio do "this", które następnie zostaną zwrócone z usługi siebie. Przyjrzyjmy się temu w akcji.

W przeciwieństwie do tego, co zrobiliśmy w przykładzie fabrycznym, nie musimy tworzyć obiektu, a następnie zwracać ten obiekt, ponieważ, jak wspomniano wiele razy wcześniej, użyliśmy słowa kluczowego 'new', więc interpreter utworzy ten obiekt, zleci delegowanie go do jego prototypu, a następnie zwróci go dla nas bez konieczności wykonywania pracy.

Po pierwsze, stwórzmy naszą' prywatną ' i pomocniczą funkcję. Powinno to wyglądać bardzo znajomo, ponieważ zrobiliśmy dokładnie to samo z naszą fabryką. Nie będę wyjaśniał, co robi każda linia, ponieważ zrobiłem to w przykładzie fabrycznym, jeśli jesteś zdezorientowany, przeczytaj ponownie przykład fabryczny.

app.service('myService', function($http, $q){
  var baseUrl = 'https://itunes.apple.com/search?term=';
  var _artist = '';
  var _finalUrl = '';

  var makeUrl = function(){
    _artist = _artist.split(' ').join('+');
    _finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK'
    return _finalUrl;
  }
});

Teraz dołączymy wszystkie nasze metody, które będą dostępne w naszym kontrolerze do 'this'.

app.service('myService', function($http, $q){
  var baseUrl = 'https://itunes.apple.com/search?term=';
  var _artist = '';
  var _finalUrl = '';

  var makeUrl = function(){
    _artist = _artist.split(' ').join('+');
    _finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK'
    return _finalUrl;
  }

  this.setArtist = function(artist){
    _artist = artist;
  }

  this.getArtist = function(){
    return _artist;
  }

  this.callItunes = function(){
    makeUrl();
    var deferred = $q.defer();
    $http({
      method: 'JSONP',
      url: _finalUrl
    }).success(function(data){
      deferred.resolve(data);
    }).error(function(){
      deferred.reject('There was an error')
    })
    return deferred.promise;
  }

});

Teraz, podobnie jak w naszej fabryce, setArtist, getArtist i callItunes będą dostępne w dowolnym kontrolerze, do którego przekazujemy myService. Oto kontroler myService (który jest prawie dokładnie taki sam jak nasz kontroler fabryczny).

app.controller('myServiceCtrl', function($scope, myService){
  $scope.data = {};
  $scope.updateArtist = function(){
    myService.setArtist($scope.data.artist);
  };

  $scope.submitArtist = function(){
    myService.callItunes()
      .then(function(data){
        $scope.data.artistData = data;
      }, function(data){
        alert(data);
      })
  }
});

Jak już wspomniałem, kiedy już naprawdę zrozumiesz, co robi "nowy", usługi są prawie identyczne z fabrykami w Angular.

 134
Author: Tyler McGinnis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-05 18:56:56

Wskazówka jest w nazwie

Usługi i fabryki są do siebie podobne. Oba dają pojedynczy obiekt, który może być wstrzykiwany do innych obiektów, a więc są często używane zamiennie.

Są przeznaczone do wykorzystania semantycznie do realizacji różnych wzorców projektowych.

Usługi służą do implementacji wzorca usług

Wzorzec usługi to taki, w którym aplikacja jest podzielona na logicznie spójne jednostki funkcjonalności. Przykład może to być accessor API lub zestaw logiki biznesowej.

Jest to szczególnie ważne w Angular, ponieważ modele Angular są zazwyczaj tylko obiektami JSON pobieranymi z serwera, więc musimy gdzieś umieścić naszą logikę biznesową.

Oto na przykład usługa Github. Wie, jak rozmawiać z Githubem. Zna adresy URL i metody. Możemy wstrzyknąć go do kontrolera, a on wygeneruje i zwróci obietnicę.

(function() {
  var base = "https://api.github.com";

  angular.module('github', [])
    .service('githubService', function( $http ) {
      this.getEvents: function() {
        var url = [
          base,
          '/events',
          '?callback=JSON_CALLBACK'
        ].join('');
        return $http.jsonp(url);
      }
    });
  )();

Fabryki wzór

Fabryki, z drugiej strony są przeznaczone do wdrożenia wzorca fabrycznego. Wzorzec fabryczny w jednym, w którym używamy funkcji fabrycznej do generowania obiektu. Zazwyczaj możemy użyć tego do budowania modeli. Oto fabryka, która zwraca Konstruktor autora:

angular.module('user', [])
  .factory('User', function($resource) {
    var url = 'http://simple-api.herokuapp.com/api/v1/authors/:id'
    return $resource(url);
  })

Wykorzystalibyśmy to tak:

angular.module('app', ['user'])
  .controller('authorController', function($scope, User) {
    $scope.user = new User();
  })

Zwróć uwagę, że fabryki zwracają również singletony.

Fabryki mogą zwrócić konstruktora

Ponieważ fabryka po prostu zwraca obiekt, może zwrócić dowolny typ obiektu, w tym funkcję konstruktora, jak widzimy powyżej.

Fabryki zwracają obiekt; usługi są nowe

Inną różnicą techniczną jest sposób, w jaki składają się usługi i fabryki. Do wygenerowania obiektu zostanie dodana funkcja service. Zostanie wywołana funkcja fabryczna, która zwróci obiekt.
  • usługi są nowymi konstruktorami.
  • fabryki są po prostu nazywane i zwracają obiekt.

Oznacza to, że w usłudze dołączamy "to", które w kontekście konstruktora wskaże obiekt w budowie.

Aby to zilustrować, oto ten sam prosty obiekt utworzony za pomocą usługi i fabryki:

angular.module('app', [])
  .service('helloService', function() {
    this.sayHello = function() {
      return "Hello!";
    }
  })
  .factory('helloFactory', function() {
    return {
      sayHello: function() {
        return "Hello!";
      }
    }
  });
 33
Author: superluminary,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-09 13:10:20

Wszystkie odpowiedzi wydają się dotyczyć serwisu i fabryki, i to jest ważne, ponieważ o to pytano. Ale ważne jest również, aby pamiętać, że istnieje kilka innych, w tym provider(), value(), i constant().

Kluczem do zapamiętania jest to, że każdy z nich jest szczególnym przypadkiem drugiego. Każdy specjalny przypadek w łańcuchu pozwala zrobić to samo z mniejszą ilością kodu. Każdy z nich ma również jakieś dodatkowe ograniczenia.

Aby zdecydować, kiedy użyć, które po prostu zobaczyć który z nich pozwala robić to, co chcesz w mniejszym kodzie. Oto zdjęcie ilustrujące, jak bardzo są one podobne:

Tutaj wpisz opis obrazka

Aby uzyskać kompletny podział krok po kroku i szybkie odniesienie do tego, kiedy używać każdego, możesz odwiedzić wpis na blogu, z którego dostałem ten obraz:

Http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory-in-angularjs/

 24
Author: Luis Perez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-19 13:36:51

App.fabryka ("fn", fn) vs.service ("fn", fn)

Budownictwo

W przypadku fabryk, Angular wywoła funkcję, aby uzyskać wynik. Jest to wynik, który jest buforowany i wstrzykiwany.

 //factory
 var obj = fn();
 return obj;

W usłudze, Angular wywoła funkcję konstruktora wywołując new . Skonstruowana funkcja jest buforowana i wstrzykiwana.

  //service
  var obj = new fn();
  return obj;

Realizacja

Fabryki zazwyczaj zwracają obiekt literalnie, ponieważ zwracana wartość jest {[14] }co jest wstrzykiwane do kontrolerów, bloków uruchamiania, dyrektyw itp

  app.factory('fn', function(){
         var foo = 0;
         var bar = 0;
         function setFoo(val) {
               foo = val;
         }
         function setBar (val){
               bar = val;
         }
         return {
                setFoo: setFoo,
                serBar: setBar
         }
  });

Funkcje serwisowe zazwyczaj niczego nie zwracają. Zamiast tego wykonują funkcje inicjalizacji i eksponowania. Funkcje mogą również odwoływać się do "tego", ponieważ zostały zbudowane przy użyciu "nowego".

app.service('fn', function () {
         var foo = 0;
         var bar = 0;
         this.setFoo = function (val) {
               foo = val;
         }
         this.setBar = function (val){
               bar = val;
         }
});

Wniosek

Jeśli chodzi o korzystanie z fabryk lub usług, oba są bardzo podobne. Są wtryskiwane do kontrolera, dyrektyw, bloku uruchamiania itp. i wykorzystywane w kodzie klienta w prawie tak samo. Są one również singletonami - co oznacza, że ta sama instancja jest dzielona pomiędzy wszystkie miejsca, w których usługa/fabryka jest wstrzykiwana.

Więc który wolisz? Oba - są tak podobne, że różnice są trywialne. Jeśli wybierzesz jeden nad drugim, po prostu pamiętaj, jak są one skonstruowane, abyś mógł je właściwie wdrożyć.

 23
Author: pixelbits,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-27 00:49:15

Spędziłem trochę czasu próbując rozgryźć różnicę.

I myślę, że funkcja factory wykorzystuje wzorzec modułu, a funkcja service wykorzystuje standardowy wzorzec konstruktora java script.

 5
Author: ps.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-10 15:04:24

Wzorzec fabryczny jest bardziej elastyczny, ponieważ może zwracać funkcje i wartości oraz obiekty.

Nie ma zbyt wiele sensu w wzorcu usług IMHO, ponieważ wszystko, co robi, można równie łatwo zrobić z fabryką. Wyjątkami mogą być:

  • Jeśli z jakiegoś powodu zależy ci na zadeklarowanym typie usługi instancyjnej - jeśli użyjesz wzorca usługi, twój konstruktor będzie typem nowej usługi.
  • Jeśli masz już funkcję konstruktora że używasz gdzie indziej, że również chcesz używać jako usługi (chociaż prawdopodobnie nie dużo użycia, jeśli chcesz wstrzyknąć coś do niego!).

Prawdopodobnie wzorzec usługi jest nieco ładniejszym sposobem tworzenia nowego obiektu z punktu widzenia składni, ale jest również droższy do tworzenia instancji. Inni wskazywali, że angular używa "nowego" do tworzenia usługi, ale nie jest to do końca prawdą - nie jest w stanie tego zrobić, ponieważ każdy konstruktor usługi ma inną liczbę parametry. To, co angular faktycznie robi, to używać wzoru fabrycznego wewnętrznie do zawijania funkcji konstruktora. Następnie wykonuje sprytne jiggery pokery, aby symulować "nowy" operator javascript, wywołując Twój konstruktor zmienną liczbą argumentów do wstrzykiwania - ale możesz pominąć ten krok, jeśli użyjesz bezpośrednio wzorca fabrycznego, co bardzo nieznacznie zwiększy wydajność Twojego kodu.

 2
Author: Dan King,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-06 15:11:37