AngularJS: serwis vs dostawca vs fabryka

Jakie są różnice między a Service, Provider i Factory w AngularJS?

Author: Robin-Hoodie, 2013-03-27

30 answers

Z listy mailingowej AngularJS dostałem niesamowity wątek , który wyjaśnia serwis vs fabryka vs dostawca i ich użycie. Zestawianie odpowiedzi:

Usługi

Składnia: module.service( 'serviceName', function );
Wynik: podczas deklarowania serviceName jako argumentu iniekcyjnego otrzymasz instancję funkcji. Innymi słowy new FunctionYouPassedToService().

Fabryki

Składnia: module.factory( 'factoryName', function );
Wynik: deklarując factoryName jako argument iniekcyjny można zostanie dostarczona wartość zwracana przez wywołanie referencji funkcji przekazanej do modułu.fabryka .

Dostawcy

Składnia: module.provider( 'providerName', function );
Wynik: deklarując providerName jako argument iniekcyjny otrzymasz (new ProviderFunction()).$get(). Funkcja konstruktora jest tworzona przed wywołaniem metody $ get - {[13] } jest referencją funkcji przekazywaną do modułu.dostawca.

Dostawcy mają tę zaletę, że mogą być konfigurowane podczas Faza konfiguracji modułu.

Zobacz tutaj aby uzyskać podany kod.

To jest to, o czym mówi Misko:]}
provide.value('a', 123);

function Controller(a) {
  expect(a).toEqual(123);
}

W tym przypadku wtryskiwacz po prostu zwraca wartość tak, jak jest. Ale co jeśli chcesz obliczyć wartość? Następnie użyj fabryki

provide.factory('b', function(a) {
  return a*2;
});

function Controller(b) {
  expect(b).toEqual(246);
}

Więc factory jest funkcją odpowiedzialną za tworzenie wartości. Zauważ, że funkcja factory może poprosić o inne zależności.

Ale co jeśli chcesz być bardziej OO i mieć klasę nazywa się Greeter?

function Greeter(a) {
  this.greet = function() {
    return 'Hello ' + a;
  }
}

Następnie, aby utworzyć instancję, musisz napisać

provide.factory('greeter', function(a) {
  return new Greeter(a);
});
Możemy wtedy poprosić o' greeter ' w kontrolerze w ten sposób.]}
function Controller(greeter) {
  expect(greeter instanceof Greeter).toBe(true);
  expect(greeter.greet()).toEqual('Hello 123');
}
Ale to zbyt słowne. Krótszy sposób napisania tego byłoby provider.service('greeter', Greeter);

Ale co jeśli chcemy skonfigurować klasę Greeter przed wstrzyknięciem? Wtedy moglibyśmy napisać

provide.provider('greeter2', function() {
  var salutation = 'Hello';
  this.setSalutation = function(s) {
    salutation = s;
  }

  function Greeter(a) {
    this.greet = function() {
      return salutation + ' ' + a;
    }
  }

  this.$get = function(a) {
    return new Greeter(a);
  };
});

Wtedy możemy to zrobić:

angular.module('abc', []).config(function(greeter2Provider) {
  greeter2Provider.setSalutation('Halo');
});

function Controller(greeter2) {
  expect(greeter2.greet()).toEqual('Halo 123');
}

Na marginesie, service, factory, i value pochodzą od dostawcy.

provider.service = function(name, Class) {
  provider.provide(name, function() {
    this.$get = function($injector) {
      return $injector.instantiate(Class);
    };
  });
}

provider.factory = function(name, factory) {
  provider.provide(name, function() {
    this.$get = function($injector) {
      return $injector.invoke(factory);
    };
  });
}

provider.value = function(name, value) {
  provider.factory(name, function() {
    return value;
  });
};
 2879
Author: Lior,
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
2020-06-20 09:12:55

Js Fiddle Demo

" Hello world " przykład z factory / service / provider:

var myApp = angular.module('myApp', []);

//service style, probably the simplest one
myApp.service('helloWorldFromService', function() {
    this.sayHello = function() {
        return "Hello, World!";
    };
});

//factory style, more involved but more sophisticated
myApp.factory('helloWorldFromFactory', function() {
    return {
        sayHello: function() {
            return "Hello, World!";
        }
    };
});
    
//provider style, full blown, configurable version     
myApp.provider('helloWorld', function() {

    this.name = 'Default';

    this.$get = function() {
        var name = this.name;
        return {
            sayHello: function() {
                return "Hello, " + name + "!";
            }
        }
    };

    this.setName = function(name) {
        this.name = name;
    };
});

//hey, we can configure a provider!            
myApp.config(function(helloWorldProvider){
    helloWorldProvider.setName('World');
});
        

function MyCtrl($scope, helloWorld, helloWorldFromFactory, helloWorldFromService) {
    
    $scope.hellos = [
        helloWorld.sayHello(),
        helloWorldFromFactory.sayHello(),
        helloWorldFromService.sayHello()];
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp">
<div ng-controller="MyCtrl">
    {{hellos}}
</div>
</body>
 817
Author: EpokK,
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-03-09 05:55:15

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 , AngularJS tworzy ją za kulisami za pomocą słowa kluczowego "new". Z tego powodu dodasz właściwości do "tego", a 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;
  }
});



3) dostawcy są jedyną usługą, którą możesz przekazać .funkcja config (). Użyj dostawcy, jeśli chcesz zapewnić konfigurację dla całego modułu obiektu usługowego przed udostępnieniem go.

app.controller(‘myProvider’, function($scope, myProvider){
  $scope.artist = myProvider.getArtist();
  $scope.data.thingFromConfig = myProvider.thingOnConfig;
});

app.provider(‘myProvider’, function(){
 //Only the next two lines are available in the app.config()
 this._artist = ‘’;
 this.thingFromConfig = ‘’;
  this.$get = function(){
    var that = this;
    return {
      getArtist: function(){
        return that._artist;
      },
      thingOnConfig: that.thingFromConfig
    }
  }
});

app.config(function(myProviderProvider){
  myProviderProvider.thingFromConfig = ‘This was set in config’;
});



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 niezależnie od właściwości dołączamy do "usługa" będzie dla nas dostępna, 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 niektóre 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'. Tworzymy je po to, aby albo użyć, albo zmodyfikuj je później.

    BaseUrl jest bazowym adresem URL wymaganym przez API iTunes.]}
  • _artist jest artystą, którego chcemy szukać
  • _finalUrl jest ostatecznym i w pełni zbudowanym adresem URL, na który zadzwonimy do iTunes
  • makeUrl to funkcja, która utworzy 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'. Cokolwiek umieścimy w "służbie" może być bezpośrednio używany wewnątrz dowolnego kontrolera, do którego przekazujemy "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 utworzonym przez nas adresem 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 AngularJS, Gorąco polecam głębokie nurkowanie na oni.

Poniżej setArtist akceptuje artystę i pozwala ustawić artystę. getArtist zwraca artystę. callItunes pierwsze wywołania makeUrl () w celu zbudowania adresu URL, którego użyjemy z naszym $http request. Następnie ustawia obiekt promise, wykonuje $http request z naszym ostatecznym adresem url, następnie ponieważ $http zwraca promise, jesteśmy w stanie wywołać.sukces lub .błąd po naszej prośbie. Następnie rozwiązujemy naszą obietnicę za pomocą danych iTunes lub odrzucamy ją za pomocą komunikat "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;
});
[20]}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 powyższym kontrolerze wykonujemy iniekcję w usłudze 'myFactory'. Następnie ustawiamy właściwości na naszym obiekcie $ scope z danymi z 'myFactory'. Jedynym trudnym kodem powyżej jest to, jeśli nigdy nie radziłeś sobie z obietnicami wcześniej. 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" (jest to dobra praktyka kodowania). Wszystkie nasze logiczne i trwałe DANE znajdują się w naszym serwisie, a 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 instancjonowana z słowo kluczowe "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 pomogą nam zrozumieć naturę usługi.

Aby naprawdę zobaczyć zmiany zachodzące podczas wywoływania funkcji słowem kluczowym 'new', stwórzmy funkcję i wywołajmy ją za pomocą 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 za każdym razem, gdy wywołamy funkcję Person używając słowa kluczowego 'new', 'this' będzie powiązane z nowo utworzonym obiektem.

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

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 naszą funkcję konstruktora Person I naszą funkcję sayName na swoim prototypie, stwórzmy instancję Person, a następnie wywołajmy funkcję sayName.

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

Więc razem kod do stworzenia konstruktora osoby, dodanie funkcji do jego prototypu, stworzenie instancja Person, a następnie wywołanie funkcji na jej 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ł obiekt - to dlatego, że tak jest. Więc najpierw wiemy, że nasz Konstruktor Person zwraca obiekt, niezależnie od tego, czy widzimy to w kodzie, czy nie. Po drugie, my wiedz, ż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 obiektu' tyler', który właśnie stworzyliśmy, zlokalizuję funkcję sayName i wywołam ją. Chwileczkę, nie widzę tego tutaj - widzę tylko imię i wiek, sprawdzę prototyp. Wygląda na to, że jest na prototypie, nazwijmy to.".

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

var Person = function(name, age){
  //The below line creates an object(obj) 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 wiedzę o tym, co naprawdę robi słowo kluczowe "nowy" w JavaScript, Tworzenie usługi w AngularJS powinno być łatwiejsze do zrozumienia.

The biggest thing to zrozumieć, podczas tworzenia usługi jest wiedząc, że usługi są tworzone z użyciem słowa kluczowego "nowy". Łącząc tę wiedzę z naszymi przykładami powyżej, powinieneś teraz rozpoznać, że będziesz dołączać swoje właściwości i metody bezpośrednio do "tego", które następnie zostaną zwrócone z samej usługi. Przyjrzyjmy się temu w akcji.

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

Po pierwsze, stwórzmy naszą' prywatną ' i pomocniczą funkcję. To powinno 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 'this' dołączymy wszystkie nasze metody, które będą dostępne w naszym kontrolerze.

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ż wcześniej wspomniałem, kiedy już naprawdę zrozumiesz, co robi "nowe", usługi są prawie identyczne z fabrykami w AngularJS.

3) dostawca

Największą rzeczą do zapamiętania o dostawcach jest to, że są to jedyne usługi, które można przekazać do aplikacji.część konfiguracyjna aplikacji. Ma to ogromne znaczenie, jeśli musisz zmienić pewną część obiektu usługowego, zanim będzie on dostępny wszędzie indziej w aplikacji. Chociaż bardzo podobne do usług / fabryk, istnieje kilka różnic, które omówimy.

Najpierw skonfigurowaliśmy naszego dostawcę w podobnie zrobiliśmy z naszą Usługą i fabryką. Poniższe zmienne są naszą' prywatną ' i funkcją pomocniczą.

app.provider('myProvider', function(){
   var baseUrl = 'https://itunes.apple.com/search?term=';
  var _artist = '';
  var _finalUrl = '';

  //Going to set this property on the config function below.
  this.thingFromConfig = ‘’;

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

* ponownie jeśli jakakolwiek część powyższego kodu jest myląca, sprawdź sekcję fabryczną, w której wyjaśniam, co to wszystko robi.

Możesz myśleć o dostawcach jako o trzech sekcjach. Pierwsza sekcja to' prywatne ' zmienne/funkcje, które zostaną później zmodyfikowane/ustawione(pokazane powyżej). Druga sekcja to zmienne / funkcje, które będą dostępne w aplikacji.funkcja config i dlatego są dostępne do zmiany, zanim będą dostępne w dowolnym innym miejscu (również pokazane powyżej). Ważne jest, aby pamiętać, że te zmienne muszą być dołączone do słowa kluczowego' this'. W naszym przykładzie tylko' thingFromConfig ' będzie dostępny do zmiany w aplikacji.config. Trzecia sekcja (pokazana poniżej) to wszystkie zmienne / funkcje, które będą dostępne w kontrolerze po przejściu usługi "myProvider" do tego konkretnego kontroler.

Podczas tworzenia usługi z dostawcą, jedynymi właściwościami / metodami, które będą dostępne w kontrolerze są te właściwości / metody, które są zwracane z funkcji $get (). Poniższy kod umieszcza $get NA 'this' (które wiemy, że w końcu zostanie zwrócone z tej funkcji). Teraz funkcja $get zwraca wszystkie metody/właściwości, które chcemy mieć dostępne w kontrolerze. Oto przykład kodu.

this.$get = function($http, $q){
    return {
      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;
      },
      setArtist: function(artist){
        _artist = artist;
      },
      getArtist: function(){
        return _artist;
      },
      thingOnConfig: this.thingFromConfig
    }
  }

Teraz pełny Kod dostawcy wygląda następująco to

app.provider('myProvider', function(){
  var baseUrl = 'https://itunes.apple.com/search?term=';
  var _artist = '';
  var _finalUrl = '';

  //Going to set this property on the config function below
  this.thingFromConfig = '';

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

  this.$get = function($http, $q){
    return {
      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;
      },
      setArtist: function(artist){
        _artist = artist;
      },
      getArtist: function(){
        return _artist;
      },
      thingOnConfig: this.thingFromConfig
    }
  }
});

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

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

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

  $scope.data.thingFromConfig = myProvider.thingOnConfig;
});

Jak wspomniano wcześniej, celem tworzenia usługi z dostawcą jest możliwość zmiany niektórych zmiennych za pośrednictwem aplikacji.funkcja config przed przekazaniem ostatniego obiektu do reszty podanie. Zobaczmy na to przykład.

app.config(function(myProviderProvider){
  //Providers are the only service you can pass into app.config
  myProviderProvider.thingFromConfig = 'This sentence was set in app.config. Providers are the only service that can be passed into config. Check out the code to see how it works';
});

Teraz możesz zobaczyć, jak' thingFromConfig 'jest pustym łańcuchem w naszym providerze, ale kiedy pojawi się on w DOM, będzie to' this sentence was set...'.

 653
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
2017-01-05 15:23:07

Wszystkie usługi są singletony ; są one tworzone raz na aplikację. Mogą być dowolnego typu, czy to prymitywne, obiektowe, funkcyjne, czy nawet instancje niestandardowego typu.

The value, factory, service, constant, i provider metody są wszystkie dostawców. Uczą wtryskiwacza, jak uruchamiać usługi.

Najbardziej gadatliwy, ale i najbardziej wszechstronny jest dostawca przepis. pozostałe cztery typy receptur-wartość, Fabryka, Serwis i Stałe - są tylko cukrem składniowym na podstawie przepisu dostawcy .

  • przepis wartość jest najprostszym przypadkiem, w którym tworzysz instancję usługi samodzielnie i dostarczasz wartość instancyjną do wtryskiwacza.
  • receptura Fabryczna daje Wtryskiwaczowi funkcję fabryczną, którą wywołuje, gdy musi utworzyć instancję usługi. Po wywołaniu funkcja factory tworzy i zwraca instancja serwisowa. Zależności usługi są podawane jako argumenty funkcji. Tak więc korzystanie z tego przepisu dodaje następujące możliwości:
      [25]} możliwość korzystania z innych usług (mieć zależności)
  • Inicjalizacja usługi
  • opóźniona / leniwa inicjalizacja
  • przepis serwisowy jest prawie taki sam jak przepis fabryczny, ale tutaj wtryskiwacz wywołuje konstruktor z nowym operatorem zamiast fabrycznego funkcja.
  • przepis Provider jest zwykle overkill . Dodaje jeszcze jedną warstwę indrection, umożliwiając konfigurację tworzenia fabryki.

    Powinieneś używać przepisu dostawcy tylko wtedy, gdy chcesz ujawnić API do konfiguracji całej aplikacji, która musi być wykonana przed uruchomienie aplikacji. Jest to zwykle interesujące tylko dla wielokrotnego użytku usługi, których zachowanie może się nieznacznie różnić między aplikacje.

  • stała receptura jest podobna do receptury wartości, z tym że pozwala na zdefiniowanie usług, które są dostępne w fazie konfiguracji . Wcześniej niż usługi tworzone przy użyciu receptury wartości. W przeciwieństwie do wartości, nie mogą być dekorowane za pomocą decorator.
  • Zobacz dokumentację dostawcy .
     513
    Author: flup,
    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-12-13 17:01:30

    Zrozumienie AngularJS Fabryka, Serwis i dostawca

    Wszystkie z nich są używane do współdzielenia obiektów singleton wielokrotnego użytku. Pomaga udostępniać kod wielokrotnego użytku w aplikacji / różnych komponentach/modułach.

    Z Docs Serwis / Fabryka:

    • leniwie utworzone – Angular tworzy instancje usługi / fabryki tylko wtedy, gdy komponent aplikacji jest od niej zależny.
    • Singletony - każdy składnik zależne od usługa otrzymuje odniesienie do pojedynczej instancji generowane przez fabrykę usług.

    Fabryka

    Fabryka jest funkcją, w której można manipulować / dodawać logikę przed utworzeniem obiektu, a następnie nowo utworzony obiekt zostanie zwrócony.

    app.factory('MyFactory', function() {
        var serviceObj = {};
        //creating an object with methods/functions or variables
        serviceObj.myFunction = function() {
            //TO DO:
        };
        //return that object
        return serviceObj;
    });
    

    Użycie

    Może być tylko zbiorem funkcji takich jak Klasa. W związku z tym, może być utworzony w różnych kontrolerach, gdy wstrzykujesz go wewnątrz funkcji kontrolera/fabryki/dyrektywy. On utworzenie instancji tylko raz na aplikację.

    Serwis

    Po prostu patrząc na usługi pomyśl o prototypie tablicy. Usługa jest funkcją, która tworzy instancję nowego obiektu za pomocą słowa kluczowego 'new'. Właściwości i funkcje można dodawać do obiektu usługowego za pomocą słowa kluczowego this. W przeciwieństwie do fabryki, nie zwraca niczego (zwraca obiekt zawierający metody/właściwości).

    app.service('MyService', function() {
        //directly binding events to this context
        this.myServiceFunction = function() {
            //TO DO:
        };
    });
    

    Użycie

    Użyj go, gdy chcesz udostępnić pojedynczy obiekt przez całą aplikację. Na przykład uwierzytelnione dane użytkownika, metody/dane z możliwością udostępniania, funkcje narzędzi itp.

    Dostawca

    Provider jest używany do tworzenia konfigurowalnego obiektu usługowego. Ustawienia usługi można skonfigurować za pomocą funkcji config. Zwraca wartość za pomocą funkcji $get(). Funkcja $get jest wykonywana w fazie uruchomienia w trybie kątowym.

    app.provider('configurableService', function() {
        var name = '';
        //this method can be be available at configuration time inside app.config.
        this.setName = function(newName) {
            name = newName;
        };
        this.$get = function() {
            var getName = function() {
                 return name;
            };
            return {
                getName: getName //exposed object to where it gets injected.
            };
        };
    });
    

    Użycie

    Kiedy musisz zapewnić konfigurację modułu dla swojej usługi obiekt przed jego udostępnieniem, np. Załóżmy, że chcesz ustawić adres URL API na podstawie swojego środowiska, jak dev, stage lub prod

    Uwaga

    Tylko provider będzie dostępny w fazie Config angular, podczas gdy serwis i fabryka nie są.

    Mam nadzieję, że to wyjaśniło Twoje zrozumienie o fabryce, usłudze i dostawcy .

     223
    Author: Pankaj Parkar,
    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
    2020-06-20 09:12:55

    Dla mnie, objawienie przyszło, kiedy zdałem sobie sprawę, że wszystkie działają w ten sam sposób: uruchamiając coś {14]} raz , zapisując otrzymaną wartość, a następnie kaszląc tę samą przechowywaną wartość kiedy odwołuję się do dependency injection.

    Powiedzmy, że mamy:

    app.factory('a', fn);
    app.service('b', fn);
    app.provider('c', fn);
    

    Różnica między tymi trzema jest taka, że:

    1. Zapisana wartość a pochodzi z running fn.
    2. b's przechowywana wartość pochodzi z new ing fn.
    3. Zapisana wartość c pochodzi z pierwszego pobrania instancji przez newing fn, a następnie uruchomienia metody $get instancji.

    Co oznacza, że wewnątrz AngularJS znajduje się coś w rodzaju obiektu pamięci podręcznej, którego wartość każdego wstrzyknięcia jest przypisywana tylko raz, kiedy zostały one wstrzyknięte po raz pierwszy, i gdzie: {]}

    cache.a = fn()
    cache.b = new fn()
    cache.c = (new fn()).$get()
    

    Dlatego używamy this w usługach i definiujemy this.$get W dostawcach.

     190
    Author: Lucia,
    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-12-13 18:14:28

    Serwis vs dostawca vs fabryka:

    Staram się to uprościć. Chodzi o podstawową koncepcję JavaScript.

    Po pierwsze, porozmawiajmy o usługach w AngularJS!

    Co to jest usługa: W AngularJS, Service jest niczym innym jak pojedynczym obiektem JavaScript, który może przechowywać kilka użytecznych metod lub właściwości. Ten singleton obiekt jest tworzony na podstawie ngApp (Angular app) i jest współdzielony między wszystkimi kontrolerami w bieżącej aplikacji. Gdy Angularjs tworzy instancję obiektu usługowego, rejestruje ten obiekt usługowy z unikalną nazwą usługi. Więc za każdym razem, gdy potrzebujemy instancji service, Angular przeszukuje rejestr pod kątem tej nazwy usługi i zwraca odniesienie do obiektu service. W taki sposób, że możemy wywołać metodę, właściwości dostępu itp. w obiekcie service. Możesz mieć pytanie, czy możesz również umieścić właściwości, metody na obiekcie scope kontrolerów! Dlaczego więc potrzebujesz obiektu serwisowego? Odpowiedzi to: usługi są współdzielone między wieloma zakresami kontrolera. Jeśli umieścisz pewne właściwości / metody w obiekcie scope kontrolera , będzie on dostępny tylko dla bieżącego zakresu. Ale kiedy zdefiniujesz metody, właściwości obiektu service, będzie on dostępny globalnie i będzie można uzyskać dostęp w dowolnym zakresie Kontrolera przez wstrzyknięcie tej usługi.

    Więc jeśli są trzy zakres kontrolera, niech to będzie controllerA, controllerB i controllerC, wszystkie będą miały tę samą instancję usługi.

    <div ng-controller='controllerA'>
        <!-- controllerA scope -->
    </div>
    <div ng-controller='controllerB'>
        <!-- controllerB scope -->
    </div>
    <div ng-controller='controllerC'>
        <!-- controllerC scope -->
    </div>
    

    Jak stworzyć serwis?

    AngularJS zapewniają różne metody rejestracji usługi. Tutaj skupimy się na trzech fabrykach metod(..), serwis(..), żywiciel(..);

    Użyj tego linku do odniesienia kodu

    Funkcja Fabryczna:

    Możemy zdefiniować funkcję fabryczną jak poniżej.

    factory('serviceName',function fnFactory(){ return serviceInstance;})
    

    AngularJS dostarcza 'factory('serviceName', fnFactory)' metodę, która pobiera dwa parametry, serviceName i funkcję JavaScript. Angular tworzy instancję usługi poprzez wywołanie funkcji fnFactory () , takiej jak poniżej.

    var serviceInstace = fnFactory();
    

    Przekazana funkcja może zdefiniować obiekt i zwrócić ten obiekt. AngularJS po prostu przechowuje odniesienie do tego obiektu do zmiennej, która jest przekazywana jako pierwszy argument. Wszystko, co zostanie zwrócone z fnFactory, będzie powiązane z serviceInstance . Zamiast zwracać obiekt, możemy również zwrócić funkcję, wartości itp., cokolwiek zwrócimy, będzie dostępne do serwisu przykład.

    Przykład:

    var app= angular.module('myApp', []);
    //creating service using factory method
    app.factory('factoryPattern',function(){
      var data={
        'firstName':'Tom',
        'lastName':' Cruise',
        greet: function(){
          console.log('hello!' + this.firstName + this.lastName);
        }
      };
    
      //Now all the properties and methods of data object will be available in our service object
      return data;
    });
    

    Funkcja Serwisowa:

    service('serviceName',function fnServiceConstructor(){})
    

    To inny sposób, możemy zarejestrować usługę. Jedyną różnicą jest sposób, w jaki AngularJS próbuje utworzyć instancję obiektu service. Tym razem angular używa słowa kluczowego ' new ' i wywołuje funkcję konstruktora jak poniżej.

    var serviceInstance = new fnServiceConstructor();
    

    W funkcji konstruktora możemy użyć słowa kluczowego' this ' do dodania właściwości / metod do obiektu service. przykład:

    //Creating a service using the service method
    var app= angular.module('myApp', []);
    app.service('servicePattern',function(){
      this.firstName ='James';
      this.lastName =' Bond';
      this.greet = function(){
        console.log('My Name is '+ this.firstName + this.lastName);
      };
    });
    

    Dostawca funkcja:

    Funkcja Provider() jest innym sposobem tworzenia usług. Niech jesteśmy zainteresowani, aby stworzyć usługę, która po prostu wyświetla jakąś wiadomość powitalną do użytkownika. Ale chcemy również zapewnić funkcjonalność taką, że użytkownik może ustawić własną wiadomość powitalną. Pod względem technicznym chcemy tworzyć konfigurowalne usługi. Jak możemy to zrobić ? Musi istnieć sposób, aby aplikacja mogła przekazać swoje niestandardowe wiadomości powitalne, a Angularjs udostępni ją fabryce / konstruktorowi funkcja, która tworzy instancję naszych usług. W takim przypadku funkcja provider () wykonuje zadanie. korzystając z funkcji provider() możemy tworzyć konfigurowalne usługi.

    Możemy tworzyć konfigurowalne usługi używając składni provider, jak podano poniżej.

    /*step1:define a service */
    app.provider('service',function serviceProviderConstructor(){});
    
    /*step2:configure the service */
    app.config(function configureService(serviceProvider){});
    

    Jak wewnętrznie działa składnia dostawcy?

    1.Obiekt Provider jest tworzony za pomocą funkcji konstruktora, którą zdefiniowaliśmy w naszej funkcji provider.

    var serviceProvider = new serviceProviderConstructor();
    

    2.Funkcja, którą przekazaliśmy w aplikacji.config (), get executed. To się nazywa Faza config, i tutaj mamy szansę dostosować naszą usługę.

    configureService(serviceProvider);
    

    3.Na koniec instancja service jest tworzona przez wywołanie metody $ get z serviceProvider.

    serviceInstance = serviceProvider.$get()
    

    Przykładowy kod do tworzenia serwisu przy użyciu składni provide:

    var app= angular.module('myApp', []);
    app.provider('providerPattern',function providerConstructor(){
      //this function works as constructor function for provider
      this.firstName = 'Arnold ';
      this.lastName = ' Schwarzenegger' ;
      this.greetMessage = ' Welcome, This is default Greeting Message' ;
      //adding some method which we can call in app.config() function
      this.setGreetMsg = function(msg){
        if(msg){
          this.greetMessage =  msg ;
        }
      };
    
      //We can also add a method which can change firstName and lastName
      this.$get = function(){
        var firstName = this.firstName;
        var lastName = this.lastName ;
        var greetMessage = this.greetMessage;
        var data={
           greet: function(){
             console.log('hello, ' + firstName + lastName+'! '+ greetMessage);
           }
        };
        return data ;
      };
    });
    
    app.config(
      function(providerPatternProvider){
        providerPatternProvider.setGreetMsg(' How do you do ?');
      }
    );
    

    Demo Robocze

    Podsumowanie:


    Factory używa funkcji factory, która zwraca instancję usługi. serviceInstance = fnFactory();

    Service użyj funkcji konstruktora i Angular wywoła tę funkcję konstruktora używając słowa kluczowego ' new ' do utworzenia instancji service. serviceInstance = new fnServiceConstructor();

    Provider definiuje funkcję providerConstructor, ta funkcja providerConstructor definiuje funkcję fabryczną $get . Angular wywołuje $get () w celu wytworzenia obiektu service. Składnia dostawcy ma dodatkową zaletę konfiguracji obiekt service zanim zostanie utworzony. serviceInstance = $get();

     137
    Author: Anant,
    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-04-08 14:06:00

    Jak zauważyło kilka osób tutaj poprawnie fabryka, dostawca, usługa, a nawet wartość i stała są wersjami tego samego. Możesz podzielić bardziej ogólne provider Na wszystkie z nich. Tak:

    Tutaj wpisz opis obrazka

    Oto artykuł, z którego pochodzi ten obrazek:

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

     88
    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:38:06

    Fabryka

    Dajesz AngularJS funkcję, AngularJS będzie buforować i wprowadzić wartość zwracaną, gdy fabryka jest wymagane.

    Przykład:

    app.factory('factory', function() {
        var name = '';
        // Return value **is** the object that will be injected
        return {
            name: name;
        }
    })
    

    Użycie:

    app.controller('ctrl', function($scope, factory) {
         $scope.name = factory.name;
    });
    

    Serwis

    Dajesz AngularJS funkcję, AngularJS wywoła nowe żeby ją stworzyć. Jest to instancja tworzona przez AngularJS, która będzie buforowana i wstrzykiwana podczas żądania usługi. Od nowe został użyty do utworzenia serwis, słowo kluczowe to jest poprawny i odnosi się do instancji.

    Przykład:

    app.service('service', function() {
         var name = '';
         this.setName = function(newName) {
             name = newName;
         }
         this.getName = function() {
             return name;
         }
    });
    

    Użycie:

    app.controller('ctrl', function($scope, service) {
       $scope.name = service.getName();
    });
    

    Dostawca

    Dajesz AngularJS funkcję, a AngularJS wywoła jej $get funkcję. Jest to wartość zwracana z funkcji $get, która będzie buforowana i wstrzykiwana, gdy usługa jest wymagana.

    Dostawcy pozwalają skonfigurować dostawcę przed AngularJS wywołuje metodę $get, aby uzyskać wstrzykiwany.

    Przykład:

    app.provider('provider', function() {
         var name = '';
         this.setName = function(newName) {
              name = newName;
         }
         this.$get = function() {
             return {
                name: name
             }
         }
    })
    

    Użycie (jako iniekcja w kontrolerze)

    app.controller('ctrl', function($scope, provider) {
        $scope.name = provider.name;
    });
    
    W tym celu należy wykonać następujące czynności:]}
    app.config(function(providerProvider) {
        providerProvider.setName('John');
    });
    
     64
    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-12-13 17:19:28

    Zauważyłem coś ciekawego podczas zabawy z dostawcami.

    Widoczność zastrzyków jest inna dla dostawców niż dla usług i fabryk. Jeśli zadeklarujesz AngularJS "stałą" (na przykład myApp.constant('a', 'Robert');), możesz wprowadzić ją do usług, fabryk i dostawców.

    Ale jeśli zadeklarujesz AngularJS "wartość" (na przykład., myApp.value('b', {name: 'Jones'});), można go wprowadzić do usług i fabryk, ale nie do funkcji tworzenia dostawcy. Można jednak wstrzyknąć go do Funkcja $get, którą definiujesz dla swojego dostawcy. Jest to wspomniane w dokumentacji AngularJS, ale łatwo to przeoczyć. Można go znaleźć na stronie % provide w sekcjach metody value i constant.

    Http://jsfiddle.net/R2Frv/1/

    <div ng-app="MyAppName">
        <div ng-controller="MyCtrl">
            <p>from Service: {{servGreet}}</p>
            <p>from Provider: {{provGreet}}</p>
        </div>
    </div>
    <script>
        var myApp = angular.module('MyAppName', []);
    
        myApp.constant('a', 'Robert');
        myApp.value('b', {name: 'Jones'});
    
        myApp.service('greetService', function(a,b) {
            this.greeter = 'Hi there, ' + a + ' ' + b.name;
        });
    
        myApp.provider('greetProvider', function(a) {
            this.firstName = a;
            this.$get = function(b) {
                this.lastName = b.name;
                this.fullName = this.firstName + ' ' + this.lastName;
                return this;
            };
        });
    
        function MyCtrl($scope, greetService, greetProvider) {
            $scope.servGreet = greetService.greeter;
            $scope.provGreet = greetProvider.fullName;
        }
    </script>
    
     57
    Author: justlooking,
    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-04-21 18:55:29

    To jest bardzo mylące część dla początkujących i próbowałem wyjaśnić to łatwymi słowami

    Usługa AngularJS: jest używana do udostępniania funkcji narzędziowych z referencją serwisową w kontrolerze. Usługa ma charakter singletonowy, więc dla jednej usługi tylko jedna instancja jest tworzona w przeglądarce i to samo odniesienie jest używane na całej stronie.

    W usłudze tworzymy nazwy funkcji jako właściwość z tym obiektem.

    AngularJS Factory: the przeznaczenie Factory jest również takie samo jak Service jednak w tym przypadku tworzymy nowy obiekt i dodajemy funkcje jako właściwości tego obiektu i na końcu zwracamy ten obiekt.

    AngularJS Provider: cel tego jest znowu taki sam, jednak Provider daje wynik swojej funkcji $get.

    Definiowanie i korzystanie z usługi, fabryki i dostawcy są wyjaśnione na http://www.dotnetfunda.com/articles/show/3156/difference-between-angularjs-service-factory-and-provider

     46
    Author: Sheo Narayan,
    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-05-23 01:44:43

    Dla mnie najlepszym i najprostszym sposobem zrozumienia różnicy jest:

    var service, factory;
    service = factory = function(injection) {}
    

    Jak AngularJS tworzy instancje poszczególnych składników (uproszczone):

    // service
    var angularService = new service(injection);
    
    // factory
    var angularFactory = factory(injection);
    

    Tak więc, dla usługi, to co staje się komponentem AngularJS jest instancją obiektu klasy, która jest reprezentowana przez funkcję service declaration. Dla fabryki jest to wynik zwracany z funkcji deklaracji fabrycznej. Fabryka może zachowywać się tak samo jak serwis:

    var factoryAsService = function(injection) {
      return new function(injection) {
        // Service content
      }
    }
    

    Najprostszy sposób myślenie jest następujące:

    • Service jest instancją obiektu singleton. Użyj usługi, jeśli chcesz dostarczyć obiekt singleton dla swojego kodu.
    • Fabryka to klasa. Użyj fabryk, jeśli chcesz zapewnić niestandardowe klasy dla kodu(nie można tego zrobić z usługami, ponieważ są one już utworzone).

    Przykład "klasy" fabrycznej jest podany w komentarzach, a także różnica między dostawcami.

     35
    Author: Lukasz Frankowski,
    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-12-13 17:03:44

    Moje wyjaśnienie w tej sprawie:

    Zasadniczo wszystkie wymienione typy (usługa, fabryka, dostawca itp.) są tylko tworzenie i konfigurowanie zmiennych globalnych (które są oczywiście globalne dla całej aplikacji), tak jak Staromodne zmienne globalne były.

    Podczas gdy zmienne globalne nie są zalecane, rzeczywiste użycie tych zmiennych globalnych polega na dostarczeniu zastrzyku zależności , przekazując zmienną do odpowiedniego kontrolera.

    Istnieje wiele poziomy komplikacji w tworzeniu wartości dla "zmiennych globalnych":

    1. stała
      Definiuje to rzeczywistą stałą, która nie powinna być modyfikowana podczas całej aplikacji, podobnie jak stałe w innych językach (coś, czego JavaScript brakuje).
    2. wartość
      Jest to modyfikowalna wartość lub obiekt i służy jako jakaś globalna zmienna, która może być nawet wstrzykiwana podczas tworzenia innych usług lub fabryk (patrz dalej te). Jednak musi to być " literalna wartość", co oznacza, że trzeba zapisać rzeczywistą wartość i nie można używać żadnej logiki obliczeniowej lub programowej (innymi słowy 39 or myText or {prop: "value"} są OK, ale 2 +2 nie jest).
    3. Fabryka
      Bardziej ogólną wartość, którą można obliczyć od razu. Działa poprzez przekazanie funkcji do AngularJS z logiką potrzebną do obliczenia wartości i AngularJS wykonuje go i zapisuje zwracaną wartość w nazwanej zmiennej.
      zauważ, że możliwe jest zwrócenie obiektu (w takim przypadku będzie on działał podobnie do usługi ) lub funkcji (która zostanie zapisana w zmiennej jako funkcja wywołania zwrotnego).
    4. serwis
      Usługa jest bardziej pomniejszoną wersją factory, która jest ważna tylko wtedy, gdy wartość jest obiektem i pozwala na zapis dowolnej logiki bezpośrednio w funkcji (tak jakby była konstruktor), a także deklarowanie i uzyskiwanie dostępu do Właściwości obiektu za pomocą słowa kluczowego this .

    5. W przeciwieństwie do usługi, która jest uproszczoną wersją factory, dostawca jest bardziej złożonym, ale bardziej elastycznym sposobem inicjalizacji "globalnych" zmiennych, z największą elastycznością jest opcja ustawiania wartości z aplikacji.config.
      Działa jak połączenie service i provider , przechodząc do provider funkcja, która ma właściwości zadeklarowane za pomocą to słowo kluczowe, które można użyć z app.config.
      wtedy musi mieć osobne $.Pobierz funkcję wykonywaną przez AngularJS po ustawieniu powyższych właściwości za pomocą pliku app.config i tego $.funkcja get zachowuje się tak samo jak powyższa funkcja factory, ponieważ jej wartość zwracana jest używana do inicjalizacji zmiennych "globalnych".
     34
    Author: yoel halb,
    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-12-13 18:25:30

    Moje zrozumienie jest bardzo proste poniżej.

    Fabryka: Po prostu tworzysz obiekt wewnątrz fabryki i zwracasz go.

    Usługa:

    Masz tylko standardową funkcję, która używa tego słowa kluczowego do zdefiniowania funkcji.

    Dostawca:

    Istnieje obiekt $get, który można zdefiniować i którego można użyć do uzyskania obiektu, który zwraca dane.

     27
    Author: sajan,
    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-12-13 17:11:52

    Podsumowanie z :

    • istnieje pięć typów receptur, które definiują sposób tworzenia obiektów: wartość , Fabryka, serwis, dostawca oraz stała.
    • Factory i Service są najczęściej stosowanymi przepisami. Jedyną różnicą między nimi jest to, że przepis Service działa lepiej dla obiektów niestandardowego typu, podczas gdy Factory może tworzyć prymitywy i funkcje JavaScript.
    • przepis Provider jest podstawowym typem receptury, a wszystkie pozostałe są tylko składniowym cukrem na nim.
    • Provider jest najbardziej złożonym typem receptury. Nie potrzebujesz go, chyba że budujesz fragment kodu wielokrotnego użytku, który wymaga globalnej konfiguracji.

    Tutaj wpisz opis obrazka


    Najlepsze odpowiedzi z Więc:

    Https://stackoverflow.com/a/26924234/165673 (https://stackoverflow.com/a/27263882/165673
    https://stackoverflow.com/a/16566144/165673

     26
    Author: Yarin,
    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:34:54

    Wszystkie dobre odpowiedzi już. Chciałbym dodać jeszcze kilka punktów na Service i Factory . Wraz z różnicą między usługą / fabryką. I można również mieć pytania takie jak:

    1. czy powinienem skorzystać z usługi lub fabryki? Co za różnica?
    2. czy robią to samo, czy zachowują się tak samo?

    Zacznijmy od różnicy między usługą a fabryka:

    1. Oba są Singletonami: ilekroć Angular znajdzie je jako zależność po raz pierwszy, tworzy pojedynczą instancję service / factory. Po utworzeniu instancji ta sama instancja jest używana na zawsze.

    2. Może być użyty do modelowania obiektu z zachowaniem: oba mogą mieć metody, wewnętrzne zmienne stanu i tak dalej. Chociaż sposób, w jaki piszesz ten kod, będzie się różnić.

    Usługi:

    Serwis jest funkcją konstruktora, a Angular utworzy jej instancję przez wywołanie new yourServiceName(). To oznacza kilka rzeczy.

    1. funkcje i zmienne instancji będą właściwościami this.
    2. nie musisz zwracać wartości. Gdy wywołanie kątowe new yourServiceName(), otrzyma obiekt this ze wszystkimi właściwościami, które na nim umieścisz.

    Przykładowy Przykład:

    angular.service('MyService', function() {
      this.aServiceVariable = "Ved Prakash"
      this.aServiceMethod = function() {
        return //code
      };
    });
    

    Gdy Angular wstrzyknie tę usługę MyService do kontrolera, który zależy od tego, że kontroler otrzyma MyService, który może wywołać działa na np. MyService.aServiceMethod ().

    Ostrożnie z this:

    Ponieważ skonstruowana usługa jest obiektem, metody wewnątrz niej mogą się do tego odwoływać, gdy są wywoływane:

    angular.service('ScoreKeeper', function($http) {
      this.score = 0;
    
      this.getScore = function() {
        return this.score;
      };
    
      this.setScore = function(newScore) {
        this.score = newScore;
      };
    
      this.addOne = function() {
        this.score++;
      };
    });
    

    Możesz pokusić się o wywołanie ScoreKeeper.setScore w łańcuchu obietnic, na przykład, jeśli zainicjowałeś wynik, pobierając go z serwera: $http.get('/score').then(ScoreKeeper.setScore). problem z tym polega na tym, że ScoreKeeper.setScore będą wywoływane z this przypisanym do null i dostaniesz błędy. Lepszym sposobem byłoby $http.get('/score').then(ScoreKeeper.setScore.bind(ScoreKeeper)). Niezależnie od tego, czy zdecydujesz się użyć tego w swoich metodach usług, czy nie, uważaj, jak je nazywasz.

    Zwracanie wartości z Service:

    Ze względu na sposób działania konstruktorów JavaScript, jeśli zwrócisz wartość złożoną (i.e., an Object) z funkcji constructor, wywołujący otrzyma ten obiekt zamiast tej instancji.

    Oznacza to, że można w zasadzie skopiować i wkleić fabryczny przykład z dołu, zastąpić factory przez service, i będzie działać:

    angular.service('MyService', function($http) {
      var api = {};
    
      api.aServiceMethod= function() {
        return $http.get('/users');
      };
      return api;
    });
    

    Więc kiedy Angular zbuduje twoją usługę za pomocą nowej metody MyService(), otrzyma ten obiekt api zamiast instancji MyService.

    Jest to zachowanie dla dowolnych złożonych wartości (obiektów, funkcji), ale nie dla typów prymitywnych.

    Fabryki:

    Fabryka jest zwykłą starą funkcją, która zwraca wartość. Wartość zwracana jest tym, co jest wstrzykiwane do rzeczy, które zależą od fabryki. Typowy wzorzec fabryczny w kątach to zwraca obiekt z funkcjami jako właściwościami, jak to:

    angular.factory('MyFactory', function($http) {
      var api = {};
    
      api.aFactoryMethod= function() {
        return $http.get('/users');
      };
    
      return api;
    });
    

    Wtryskiwana wartość zależności fabrycznej jest zwracana przez fabrykę wartość, a nie musi to być obiekt. Może to być funkcja

    Odpowiedzi na powyższe 1 i 2 pytania:

    W większości przypadków, po prostu trzymaj się używania fabryk do wszystkiego. Ich zachowanie jest łatwiejsze do zrozumienia. Nie ma wyboru. o tym, czy zwrócić wartość, czy nie, a ponadto, no bugs to be przedstawię cię, jeśli zrobisz coś złego.

    Nadal nazywam je "usługami", Kiedy mówię o wstrzykiwaniu ale jako zależności.

    Zachowanie serwisu/fabryki jest bardzo podobne, a niektórzy powiedzą to jedno i drugie jest w porządku. To w pewnym sensie prawda, ale łatwiej jest mi postępuj zgodnie z radami John Papa ' s style guide i po prostu trzymaj się fabryki.**

     23
    Author: Ved,
    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-10-10 07:34:44

    [3]}dodatkowym wyjaśnieniem jest to, że fabryki mogą tworzyć funkcje / prymitywy, podczas gdy usługi nie mogą. Sprawdź to jsFiddle na podstawie epok ' s: http://jsfiddle.net/skeller88/PxdSP/1351/.

    Fabryka zwraca funkcję, którą można wywołać:

    myApp.factory('helloWorldFromFactory', function() {
      return function() {
        return "Hello, World!";
      };
    });
    

    Fabryka może również zwrócić obiekt za pomocą metody, którą można wywołać:

    myApp.factory('helloWorldFromFactory', function() {
      return {
        sayHello: function() {
          return "Hello, World!";
        }
      };
    });
    

    Usługa zwraca obiekt z metodą, którą można wywołać:

    myApp.service('helloWorldFromService', function() {
      this.sayHello = function() {
         return "Hello, World!";
      };
    });
    

    Aby uzyskać więcej informacji, zobacz post Napisałem o różnicy: http://www.shanemkeller.com/tldr-services-vs-factories-in-angular/

     17
    Author: skeller88,
    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-31 10:22:22

    Są już dobre odpowiedzi, ale chcę się tym podzielić.

    Po Pierwsze: Provider jest sposobem / przepisem na stworzenie service (singleton object), który ma być wstrzykiwany przez $injector (jak AngulaJS idzie o wzorzec IoC).

    I Wartość, Fabryka, usługa i stała (4 sposoby) - składnia cukru nad dostawca sposób/recepcja.

    Jest Service vs Factory część została pokryta: https://www.youtube.com/watch?v=BLzNCkPn3ao

    Serwis jest o new Słowo kluczowe faktycznie, które jak wiemy robi 4 rzeczy:

    1. tworzy nowy obiekt
    2. łączy go ze swoim prototype obiektem
    3. łączy context z this
    4. i zwraca this

    I Factory jest wzorcem fabrycznym-zawiera funkcje zwracające obiekty takie jak ta usługa.

    1. możliwość korzystania z innych usług (mieć zależności)
    2. serwis inicjalizacja
    3. opóźniona / leniwa inicjalizacja

    I ten prosty / krótki filmik:: https://www.youtube.com/watch?v=HvTZbQ_hUZY (tam widać jak przechodzą z fabryki do dostawcy)

    Przepis Provider jest używany głównie w konfiguracji aplikacji, zanim aplikacja zostanie w pełni uruchomiona / zainicjowana.

     17
    Author: ses,
    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-23 14:04:46

    Po przeczytaniu tych wszystkich postów stworzyło to dla mnie więcej zamieszania.. Ale nadal wszystko jest warte informacji.. w końcu znalazłem następującą tabelę, która da informacje z prostym porównaniem

    • wtryskiwacz wykorzystuje receptury do tworzenia dwóch typów obiektów: usługi i obiektów specjalnego przeznaczenia
    • Istnieje pięć typów receptur, które definiują sposób tworzenia obiektów: wartość, Fabryka, usługa, dostawca i stała.
    • Fabryka i Serwis to najczęściej używane przepisy. Jedyną różnicą między nimi jest to, że przepis Usługi działa lepiej dla obiektów niestandardowego typu, podczas gdy fabryka może produkować prymitywy i funkcje JavaScript.
    • przepis Provider jest podstawowym typem receptury, a wszystkie pozostałe są tylko składniowym cukrem na nim.
    • Provider jest najbardziej złożonym typem receptury. Nie potrzebujesz go, chyba że budujesz fragment kodu wielokrotnego użytku, który wymaga globalnej konfiguracji.
    • Wszystkie obiekty specjalnego przeznaczenia z wyjątkiem kontrolera są zdefiniowane za pomocą receptur fabrycznych.

    Tutaj wpisz opis obrazka

    I dla początkujących zrozumieć: - to może nie poprawny przypadek użycia, ale na wysokim poziomie to jest to, co usecase dla tych trzech.

    1. Jeśli chcesz użyć w module Angular Config funkcji należy utworzyć jako provider

    angular.module('myApp').config(function($testProvider){
    $testProvider.someFunction();
    })
      [[4]}Połączenie Ajax lub integracja osób trzecich musi być usługa .
    1. do manipulacji danymi utwórz go jako fabryka

    Dla podstawowych scenariuszy fabryka i serwis zachowują się tak samo.

     14
    Author: BEJGAM SHIVA PRASAD,
    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-07-27 06:48:50

    Oto kod broilerplate, który wymyśliłem jako szablon kodu dla obiektu Factory w AngularjS. Użyłem samochodu / CarFactory jako przykład do zilustrowania. Umożliwia prostą implementację kodu w kontrolerze.

         <script>
            angular.module('app', [])
                .factory('CarFactory', function() {
    
                    /**
                     * BroilerPlate Object Instance Factory Definition / Example
                     */
                    this.Car = function() {
    
                        // initialize instance properties
                        angular.extend(this, {
                            color           : null,
                            numberOfDoors   : null,
                            hasFancyRadio   : null,
                            hasLeatherSeats : null
                        });
    
                        // generic setter (with optional default value)
                        this.set = function(key, value, defaultValue, allowUndefined) {
    
                            // by default,
                            if (typeof allowUndefined === 'undefined') {
                                // we don't allow setter to accept "undefined" as a value
                                allowUndefined = false;
                            }
                            // if we do not allow undefined values, and..
                            if (!allowUndefined) {
                                // if an undefined value was passed in
                                if (value === undefined) {
                                    // and a default value was specified
                                    if (defaultValue !== undefined) {
                                        // use the specified default value
                                        value = defaultValue;
                                    } else {
                                        // otherwise use the class.prototype.defaults value
                                        value = this.defaults[key];
                                    } // end if/else
                                } // end if
                            } // end if
    
                            // update 
                            this[key] = value;
    
                            // return reference to this object (fluent)
                            return this;
    
                        }; // end this.set()
    
                    }; // end this.Car class definition
    
                    // instance properties default values
                    this.Car.prototype.defaults = {
                        color: 'yellow',
                        numberOfDoors: 2,
                        hasLeatherSeats: null,
                        hasFancyRadio: false
                    };
    
                    // instance factory method / constructor
                    this.Car.prototype.instance = function(params) {
                        return new 
                            this.constructor()
                                    .set('color',           params.color)
                                    .set('numberOfDoors',   params.numberOfDoors)
                                    .set('hasFancyRadio',   params.hasFancyRadio)
                                    .set('hasLeatherSeats', params.hasLeatherSeats)
                        ;
                    };
    
                    return new this.Car();
    
                }) // end Factory Definition
                .controller('testCtrl', function($scope, CarFactory) {
    
                    window.testCtrl = $scope;
    
                    // first car, is red, uses class default for:
                    // numberOfDoors, and hasLeatherSeats
                    $scope.car1     = CarFactory
                                        .instance({
                                            color: 'red'
                                        })
                                    ;
    
                    // second car, is blue, has 3 doors, 
                    // uses class default for hasLeatherSeats
                    $scope.car2     = CarFactory
                                        .instance({
                                            color: 'blue',
                                            numberOfDoors: 3
                                        })
                                    ;
                    // third car, has 4 doors, uses class default for 
                    // color and hasLeatherSeats
                    $scope.car3     = CarFactory
                                        .instance({
                                            numberOfDoors: 4
                                        })
                                    ;
                    // sets an undefined variable for 'hasFancyRadio',
                    // explicitly defines "true" as default when value is undefined
                    $scope.hasFancyRadio = undefined;
                    $scope.car3.set('hasFancyRadio', $scope.hasFancyRadio, true);
    
                    // fourth car, purple, 4 doors,
                    // uses class default for hasLeatherSeats
                    $scope.car4     = CarFactory
                                        .instance({
                                            color: 'purple',
                                            numberOfDoors: 4
                                        });
                    // and then explicitly sets hasLeatherSeats to undefined
                    $scope.hasLeatherSeats = undefined;
                    $scope.car4.set('hasLeatherSeats', $scope.hasLeatherSeats, undefined, true);
    
                    // in console, type window.testCtrl to see the resulting objects
    
                });
        </script>
    

    Oto prostszy przykład. Używam kilku bibliotek stron trzecich, które oczekują" pozycji " obiektu eksponującego szerokość i długość geograficzną, ale poprzez różne właściwości obiektu. Nie chciałem włamywać się do kodu dostawcy, więc zmieniłem" pozycję " obiektów, które przechodziłem w pobliżu.

        angular.module('app')
    .factory('PositionFactory', function() {
    
        /**
         * BroilerPlate Object Instance Factory Definition / Example
         */
        this.Position = function() {
    
            // initialize instance properties 
            // (multiple properties to satisfy multiple external interface contracts)
            angular.extend(this, {
                lat         : null,
                lon         : null,
                latitude    : null,
                longitude   : null,
                coords: {
                    latitude: null,
                    longitude: null
                }
            });
    
            this.setLatitude = function(latitude) {
                this.latitude           = latitude;
                this.lat                = latitude;
                this.coords.latitude    = latitude;
                return this;
            };
            this.setLongitude = function(longitude) {
                this.longitude          = longitude;
                this.lon                = longitude;
                this.coords.longitude   = longitude;
                return this;
            };
    
        }; // end class definition
    
        // instance factory method / constructor
        this.Position.prototype.instance = function(params) {
            return new 
                this.constructor()
                        .setLatitude(params.latitude)
                        .setLongitude(params.longitude)
            ;
        };
    
        return new this.Position();
    
    }) // end Factory Definition
    
    .controller('testCtrl', function($scope, PositionFactory) {
        $scope.position1 = PositionFactory.instance({latitude: 39, longitude: 42.3123});
        $scope.position2 = PositionFactory.instance({latitude: 39, longitude: 42.3333});
    }) // end controller
    

    ;

     13
    Author: James Earlywine,
    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-30 15:57:37

    Używając jako odniesienie tej strony i dokumentacji (która wydaje się znacznie ulepszona od czasu ostatniego spojrzenia), złożyłem następujące prawdziwe demo świata, które wykorzystuje 4 z 5 smaków dostawcy; wartość, stała, Fabryka i dostawca full blown.

    HTML:

    <div ng-controller="mainCtrl as main">
        <h1>{{main.title}}*</h1>
        <h2>{{main.strapline}}</h2>
        <p>Earn {{main.earn}} per click</p>
        <p>You've earned {{main.earned}} by clicking!</p>
        <button ng-click="main.handleClick()">Click me to earn</button>
        <small>* Not actual money</small>
    </div>
    

    App

    var app = angular.module('angularProviders', []);
    
    // A CONSTANT is not going to change
    app.constant('range', 100);
    
    // A VALUE could change, but probably / typically doesn't
    app.value('title', 'Earn money by clicking');
    app.value('strapline', 'Adventures in ng Providers');
    
    // A simple FACTORY allows us to compute a value @ runtime.
    // Furthermore, it can have other dependencies injected into it such
    // as our range constant.
    app.factory('random', function randomFactory(range) {
        // Get a random number within the range defined in our CONSTANT
        return Math.random() * range;
    });
    
    // A PROVIDER, must return a custom type which implements the functionality 
    // provided by our service (see what I did there?).
    // Here we define the constructor for the custom type the PROVIDER below will 
    // instantiate and return.
    var Money = function(locale) {
    
        // Depending on locale string set during config phase, we'll
        // use different symbols and positioning for any values we 
        // need to display as currency
        this.settings = {
            uk: {
                front: true,
                currency: '£',
                thousand: ',',
                decimal: '.'
            },
            eu: {
                front: false,
                currency: '€',
                thousand: '.',
                decimal: ','
            }
        };
    
        this.locale = locale;
    };
    
    // Return a monetary value with currency symbol and placement, and decimal 
    // and thousand delimiters according to the locale set in the config phase.
    Money.prototype.convertValue = function(value) {
    
        var settings = this.settings[this.locale],
            decimalIndex, converted;
    
        converted = this.addThousandSeparator(value.toFixed(2), settings.thousand);
    
        decimalIndex = converted.length - 3;
    
        converted = converted.substr(0, decimalIndex) +
            settings.decimal +
            converted.substr(decimalIndex + 1);    
    
        converted = settings.front ?
                settings.currency + converted : 
                converted + settings.currency; 
    
        return converted;   
    };
    
    // Add supplied thousand separator to supplied value
    Money.prototype.addThousandSeparator = function(value, symbol) {
       return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, symbol);
    };
    
    // PROVIDER is the core recipe type - VALUE, CONSTANT, SERVICE & FACTORY
    // are all effectively syntactic sugar built on top of the PROVIDER construct
    // One of the advantages of the PROVIDER is that we can configure it before the
    // application starts (see config below).
    app.provider('money', function MoneyProvider() {
    
        var locale;
    
        // Function called by the config to set up the provider
        this.setLocale = function(value) {
            locale = value;   
        };
    
        // All providers need to implement a $get method which returns
        // an instance of the custom class which constitutes the service
        this.$get = function moneyFactory() {
            return new Money(locale);
        };
    });
    
    // We can configure a PROVIDER on application initialisation.
    app.config(['moneyProvider', function(moneyProvider) {
        moneyProvider.setLocale('uk');
        //moneyProvider.setLocale('eu'); 
    }]);
    
    // The ubiquitous controller
    app.controller('mainCtrl', function($scope, title, strapline, random, money) {
    
        // Plain old VALUE(s)
        this.title = title;
        this.strapline = strapline;
    
        this.count = 0;
    
        // Compute values using our money provider    
        this.earn = money.convertValue(random); // random is computed @ runtime
        this.earned = money.convertValue(0);
    
        this.handleClick = function() { 
            this.count ++;
            this.earned = money.convertValue(random * this.count);
        };
    });
    

    Praca demo .

     12
    Author: net.uk.sweet,
    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-30 20:04:12

    Ta odpowiedź dotyczy tematu / pytania

    Jak Fabryka, usługa i stała - to tylko cukier składniowy na recepturze dostawcy?

    Lub

    Jak Fabryka, serwis i dostawcy są simailar wewnętrznie

    W Zasadzie to co się dzieje to

    Kiedy tworzysz factory() ustawia function podany w drugim argumencie $get i zwraca(provider(name, {$get:factoryFn })), wszystko co dostajesz to provider, ale nie ma innej właściwości/metody niż $get Z to provider (oznacza, że nie możesz tego skonfigurować)

    Kod źródłowy fabryki

    function factory(name, factoryFn, enforce) {
        return provider(name, {
          $get: enforce !== false ? enforceReturnValue(name, factoryFn) : factoryFn
        });
    };
    

    Podczas tworzenia service() zwraca factory() z function, który wstrzykuje constructor (zwraca instancję konstruktora, którą podałeś w swojej usłudze) i zwraca ją

    Kod źródłowy serwisu

    function service(name, constructor) {
        return factory(name, ['$injector', function($injector) {
          return $injector.instantiate(constructor);
        }]);
    };
    

    Więc zasadniczo w obu przypadkach w końcu dostajesz providers $get set do funkcji , którą podałeś, ale możesz dać coś więcej niż $get jak można pierwotnie podać w provider() dla config block

     12
    Author: A.B,
    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-11-06 02:07:53

    Znam wiele doskonałych odpowiedzi, ale muszę podzielić się swoim doświadczeniem z używania
    1. service dla większości przypadków default
    2. factory używane do tworzenia usługi, że konkretna instancja

    // factory.js ////////////////////////////
    (function() {
    'use strict';
    angular
        .module('myApp.services')
        .factory('xFactory', xFactoryImp);
    xFactoryImp.$inject = ['$http'];
    
    function xFactoryImp($http) {
        var fac = function (params) {
            this._params = params; // used for query params
        };
    
        fac.prototype.nextPage = function () {
            var url = "/_prc";
    
            $http.get(url, {params: this._params}).success(function(data){ ...
        }
        return fac;
    }
    })();
    
    // service.js //////////////////////////
    (function() {
    'use strict';
    angular
        .module('myApp.services')
        .service('xService', xServiceImp);
    xServiceImp.$inject = ['$http'];
    
    function xServiceImp($http) {  
        this._params = {'model': 'account','mode': 'list'};
    
        this.nextPage = function () {
            var url = "/_prc";
    
            $http.get(url, {params: this._params}).success(function(data){ ...
        }       
    }
    })();
    

    I używając:

    controller: ['xFactory', 'xService', function(xFactory, xService){
    
            // books = new instance of xFactory for query 'book' model
            var books = new xFactory({'model': 'book', 'mode': 'list'});
    
            // accounts = new instance of xFactory for query 'accounts' model
            var accounts = new xFactory({'model': 'account', 'mode': 'list'});
    
            // accounts2 = accounts variable
            var accounts2 = xService;
    ... 
    
     11
    Author: nguyên,
    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-04-07 01:25:52

    Trochę za późno na przyjęcie. Ale pomyślałem, że jest to bardziej pomocne dla tych, którzy chcieliby dowiedzieć się (lub mieć jasność) na temat opracowywania niestandardowych usług Angular JS przy użyciu metod fabrycznych, usług i dostawców.

    Natknąłem się na ten film, który wyjaśnia jasno o metodologii fabryki, usług i dostawców dla rozwoju niestandardowych usług AngularJS:

    Https://www.youtube.com/watch?v=oUXku28ex-M

    Kod Źródłowy: http://www.techcbt.com/Post/353/Angular-JS-basics/how-to-develop-angularjs-custom-service

    Zamieszczony tutaj Kod jest kopiowany prosto z powyższego źródła, dla korzyści czytelników.

    [4]} Kod usługi niestandardowej "fabrycznej" jest następujący (co dotyczy zarówno wersji synchronicznej, jak i asynchronicznej wraz z wywołaniem usługi http):

    var app = angular.module("app", []);
    app.controller('emp', ['$scope', 'calcFactory',
      function($scope, calcFactory) {
        $scope.a = 10;
        $scope.b = 20;
    
        $scope.doSum = function() {
          //$scope.sum = calcFactory.getSum($scope.a, $scope.b); //synchronous
          calcFactory.getSum($scope.a, $scope.b, function(r) { //aynchronous
            $scope.sum = r;
          });
        };
    
      }
    ]);
    
    app.factory('calcFactory', ['$http', '$log',
      function($http, $log) {
        $log.log("instantiating calcFactory..");
        var oCalcService = {};
    
        //oCalcService.getSum = function(a,b){
        //	return parseInt(a) + parseInt(b);
        //};
    
        //oCalcService.getSum = function(a, b, cb){
        //	var s = parseInt(a) + parseInt(b);
        //	cb(s);
        //};
    
        oCalcService.getSum = function(a, b, cb) { //using http service
    
          $http({
            url: 'http://localhost:4467/Sum?a=' + a + '&b=' + b,
            method: 'GET'
          }).then(function(resp) {
            $log.log(resp.data);
            cb(resp.data);
          }, function(resp) {
            $log.error("ERROR occurred");
          });
        };
    
        return oCalcService;
      }
    ]);

    Kod metodologii "service" dla usług niestandardowych (jest to dość podobne do "factory", ale różni się od składni punkt widzenia): {]}

    var app = angular.module("app", []);
    app.controller('emp', ['$scope', 'calcService', function($scope, calcService){
    	$scope.a = 10;
    	$scope.b = 20;
    
    	$scope.doSum = function(){
    		//$scope.sum = calcService.getSum($scope.a, $scope.b);
    		
    		calcService.getSum($scope.a, $scope.b, function(r){
    			$scope.sum = r;
    		});		
    	};
    
    }]);
    
    app.service('calcService', ['$http', '$log', function($http, $log){
    	$log.log("instantiating calcService..");
    	
    	//this.getSum = function(a,b){
    	//	return parseInt(a) + parseInt(b);
    	//};
    
    	//this.getSum = function(a, b, cb){
    	//	var s = parseInt(a) + parseInt(b);
    	//	cb(s);
    	//};
    
    	this.getSum = function(a, b, cb){
    		$http({
    			url: 'http://localhost:4467/Sum?a=' + a + '&b=' + b,
    			method: 'GET'
    		}).then(function(resp){
    			$log.log(resp.data);
    			cb(resp.data);
    		},function(resp){
    			$log.error("ERROR occurred");
    		});
    	};
    
    }]);

    Kod metodologii "provider" dla niestandardowych usług (jest to konieczne, jeśli chcesz opracować usługę, która może być skonfigurowana):

    var app = angular.module("app", []);
    app.controller('emp', ['$scope', 'calcService', function($scope, calcService){
    	$scope.a = 10;
    	$scope.b = 20;
    
    	$scope.doSum = function(){
    		//$scope.sum = calcService.getSum($scope.a, $scope.b);
    		
    		calcService.getSum($scope.a, $scope.b, function(r){
    			$scope.sum = r;
    		});		
    	};
    
    }]);
    
    app.provider('calcService', function(){
    
    	var baseUrl = '';
    
    	this.config = function(url){
    		baseUrl = url;
    	};
    
    	this.$get = ['$log', '$http', function($log, $http){
    		$log.log("instantiating calcService...")
    		var oCalcService = {};
    
    		//oCalcService.getSum = function(a,b){
    		//	return parseInt(a) + parseInt(b);
    		//};
    
    		//oCalcService.getSum = function(a, b, cb){
    		//	var s = parseInt(a) + parseInt(b);
    		//	cb(s);	
    		//};
    
    		oCalcService.getSum = function(a, b, cb){
    
    			$http({
    				url: baseUrl + '/Sum?a=' + a + '&b=' + b,
    				method: 'GET'
    			}).then(function(resp){
    				$log.log(resp.data);
    				cb(resp.data);
    			},function(resp){
    				$log.error("ERROR occurred");
    			});
    		};		
    
    		return oCalcService;
    	}];
    
    });
    
    app.config(['calcServiceProvider', function(calcServiceProvider){
    	calcServiceProvider.config("http://localhost:4467");
    }]);

    Wreszcie interfejs użytkownika, który działa z którąkolwiek z powyższych usług:

    <html>
    <head>
    	<title></title>
    	<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js" ></script>
    	<script type="text/javascript" src="t03.js"></script>
    </head>
    <body ng-app="app">
    	<div ng-controller="emp">
    		<div>
    			Value of a is {{a}},
    			but you can change
    			<input type=text ng-model="a" /> <br>
    
    			Value of b is {{b}},
    			but you can change
    			<input type=text ng-model="b" /> <br>
    
    		</div>
    		Sum = {{sum}}<br>
    		<button ng-click="doSum()">Calculate</button>
    	</div>
    </body>
    </html>
     10
    Author: user203687,
    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-28 19:26:13

    Dla jasności, ze źródła AngularJS, można zobaczyć usługę wywołującą funkcję factory, która z kolei wywołuje funkcję provider:

    function factory(name, factoryFn) { 
        return provider(name, { $get: factoryFn }); 
    }
    
    function service(name, constructor) {
        return factory(name, ['$injector', function($injector) {
          return $injector.instantiate(constructor);
        }]);
    }
    
     10
    Author: Ricardo Rossi,
    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-01-21 20:44:58

    W 1999 roku, w 1999 roku, po raz pierwszy w historii, w Polsce i za granicą, w 1999 roku, w 1999 roku, w 1999 roku, w 1999 roku, w 1999 roku, w 1999 roku, w 1999 roku, w 1999 roku, w 1999 roku, w 1999 roku, w 1999 roku, w 1999 roku, w 1999 roku, w]}

    Serwis :

    Składnia:

    App.js

     var app = angular.module('ServiceExample',[]);
     var serviceExampleController =
                  app.controller('ServiceExampleController', ServiceExampleController);
     var serviceExample = app.service('NameOfTheService', NameOfTheService);
    
     ServiceExampleController.$inject = ['NameOfTheService'] //protects from minification of js files
    
    function ServiceExampleController(NameOfTheService){
         serviceExampleController = this;
         serviceExampleController.data = NameOfTheService.getSomeData();
     }
    
    function NameOfTheService(){
         nameOfTheService = this;
         nameOfTheService.data = "Some Data";
         nameOfTheService.getSomeData = function(){
               return nameOfTheService.data;
         }     
    }
    

    Indeks.html

    <div ng-controller = "ServiceExampleController as serviceExample">
       {{serviceExample.data}}
    </div>
    

    Cechy usługi:

    1. leniwie utworzony : jeśli nie zostanie wstrzyknięty, nigdy nie zostanie utworzony. Więc aby go użyć, trzeba będzie wstrzyknąć go do moduł.
    2. Singleton : jeśli zostanie wstrzyknięty do wielu modułów, wszystkie będą miały dostęp tylko do jednej konkretnej instancji. Dlatego bardzo wygodne udostępnianie danych między różnymi kontrolerami.

    Fabryka

    Najpierw spójrzmy na składnię:

    App.js :

    var app = angular.module('FactoryExample',[]);
    var factoryController = app.controller('FactoryController', FactoryController);
    var factoryExampleOne = app.factory('NameOfTheFactoryOne', NameOfTheFactoryOne);
    var factoryExampleTwo = app.factory('NameOfTheFactoryTwo', NameOfTheFactoryTwo);
    
    //first implementation where it returns a function
    function NameOfTheFactoryOne(){
       var factory = function(){
          return new SomeService();
        }
       return factory;
    }
    
    //second implementation where an object literal would be returned
    function NameOfTheFactoryTwo(){
       var factory = {
          getSomeService : function(){
              return new SomeService();
           }
        };
       return factory;
    }
    

    Teraz używając powyższych dwóch w kontrolerze:

     var factoryOne = NameOfTheFactoryOne() //since it returns a function
     factoryOne.someMethod();
    
     var factoryTwo = NameOfTheFactoryTwo.getSomeService(); //accessing the object
     factoryTwo.someMethod();
    

    Cechy fabryki:

    1. podąża za fabrycznym wzorcem projektowym. Fabryka jest centralnym miejscem, które produkuje nowe obiekty lub funkcje.
    2. produkuje nie tylko singleton, ale także konfigurowalne usługi.
    3. metoda .service() jest fabryką , która zawsze produkuje ten sam typ usługi, który jest singletonem, i bez łatwego sposobu konfiguracji jego zachowania. Ta metoda .service() jest zwykle używana jako skrót do czegoś, co nie wymaga żadnej konfiguracji.

    Dostawca

    Spójrzmy jeszcze raz na składnia pierwsza:

    angular.module('ProviderModule', [])
    .controller('ProviderModuleController', ProviderModuleController)
    .provider('ServiceProvider', ServiceProvider)
    .config(Config); //optional
    
    Config.$inject = ['ServiceProvider'];
    function Config(ServiceProvider) {
      ServiceProvider.defaults.maxItems = 10; //some default value
    }
    
    
    ProviderModuleController.$inject = ['ServiceProvider'];
    function ProviderModuleController(ServiceProvider) {
      //some methods
    }
    
    function ServiceProvider() {
      var provider = this;
    
      provider.defaults = {
        maxItems: 10
      };
    
      provider.$get = function () {
        var someList = new someListService(provider.defaults.maxItems);
    
        return someList;
      };
    }
    
    }
    

    Cechy dostawcy:

    1. Provider jest najbardziej elastyczną metodą tworzenia usług w Angular.
    2. nie tylko możemy stworzyć fabrykę, która jest dynamicznie konfigurowalna, ale w momencie korzystania z fabryki, za pomocą metody provider, możemy skonfigurować fabrykę tylko raz podczas bootstrapowania całej naszej aplikacji.
    3. fabryka może być następnie używana w całej aplikacji z ustawieniami niestandardowymi. Innymi słowy, my można skonfigurować tę fabrykę przed uruchomieniem aplikacji. W rzeczywistości w dokumentacji angular jest wspomniane, że metoda provider jest tym, co faktycznie jest wykonywane za kulisami, gdy konfigurujemy nasze usługi za pomocą metod .service lub .factory.
    4. {[9] } jest funkcją, która jest bezpośrednio dołączona do instancji provider. Funkcja ta jest funkcją fabryczną . Innymi słowy, jest to tak samo jak ta, której używamy, aby dostarczyć do metody .factory. W tym funkcjonalność, tworzymy własną usługę. ta właściwość $get, która jest funkcją, sprawia, że dostawca jest dostawcą . AngularJS oczekuje, że Dostawca będzie miał właściwość $ get, której wartość jest funkcją, którą Angular potraktuje jako funkcję fabryczną. ale to, co sprawia, że cała konfiguracja Dostawcy jest wyjątkowa, to fakt, że możemy dostarczyć jakiś obiekt config wewnątrz usługodawcy, a to zwykle zawiera domyślne wartości, które możemy później zastąpić w kroku, w którym możemy skonfiguruj całą aplikację.
     9
    Author: Pritam Banerjee,
    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-09 09:31:42

    Factory: fabryka faktycznie tworzysz obiekt wewnątrz fabryki i zwracasz go.
    service: usługa, którą po prostu masz standardową funkcję, która używa tego słowa kluczowego do zdefiniowania funkcji.
    provider: The provider there ' s a $ get you define and it can be used to get the object that returns the data.

     7
    Author: Mohanrajan,
    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-04 11:12:38

    Zasadniczo dostawca, fabryka i usługa to wszystkie usługi. Fabryka jest szczególnym przypadkiem usługi, gdy wszystko czego potrzebujesz to funkcja $ get (), pozwalająca na pisanie jej z mniejszą ilością kodu.

    Główne różnice między usługami, fabrykami i dostawcami to ich złożoność. Usługi są najprostszą formą, fabryki są nieco bardziej solidne, a Dostawcy można konfigurować w czasie wykonywania.

    Oto podsumowanie, kiedy używać każdego z nich:

    Factory : The wartość, którą podajesz, musi zostać obliczona na podstawie innych danych.

    Service: zwracasz obiekt z metodami.

    Provider: chcesz być w stanie skonfigurować w fazie konfiguracji obiekt, który zostanie utworzony przed jego utworzeniem. Korzystaj z dostawcy głównie w konfiguracji aplikacji, zanim aplikacja zostanie w pełni zainicjowana.

     7
    Author: eGhoul,
    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-28 11:41:07

    1.Usługi to obiekty singleton, które są tworzone w razie potrzeby i nigdy nie są czyszczone do końca cyklu życia aplikacji (gdy przeglądarka jest zamknięta). Kontrolery są niszczone i czyszczone, gdy nie są już potrzebne.

    2.Najprostszym sposobem utworzenia usługi jest użycie metody factory (). Metoda factory () pozwala nam zdefiniować usługę zwracając obiekt, który zawiera funkcje usługi i dane usługi. Funkcja definicji usługi jest wtedy, gdy umieść nasze usługi iniekcyjne, takie jak $http i $ Q. Ex:

    angular.module('myApp.services')
    .factory('User', function($http) { // injectables go here
    var backendUrl = "http://localhost:3000"; var service = {
        // our factory definition
    user: {},
    setName: function(newName) {
          service.user['name'] = newName;
        },
    setEmail: function(newEmail) { service.user['email'] = newEmail;
    },
    save: function() {
    return $http.post(backendUrl + '/users', { user: service.user
    }); }
    };
    return service; });
    

    Używanie funkcji factory () w naszej aplikacji

    Użycie fabryki w naszej aplikacji jest łatwe, ponieważ możemy ją po prostu wstrzyknąć tam, gdzie jest potrzebna w czasie pracy.

    angular.module('myApp')
    .controller('MainController', function($scope, User) {
      $scope.saveUser = User.save;
    });
    
    1. z drugiej strony metoda service() pozwala nam stworzyć usługę poprzez zdefiniowanie funkcji konstruktora. Możemy użyć prototypowego obiektu do zdefiniowania naszej usługi, zamiast surowego obiektu javascript. Podobnie jak w metodzie factory (), ustawimy również injectables w definicji funkcji.
    2. NAJNIŻSZYM sposobem tworzenia usługi jest użycie metody provide (). Jest to jedyny sposób na stworzenie usługi, którą możemy skonfigurować za pomocą.funkcja config (). W przeciwieństwie do poprzednich metod, ustawimy zastrzyki w zdefiniowanym tym.$get () definicja funkcji.
     4
    Author: Shankar Gangadhar,
    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-10-30 23:39:31

    Cukrem składniowym jest różnica . Potrzebny jest tylko dostawca. Lub innymi słowy tylko provider jest rzeczywisty kąt, wszystkie pozostałe są wyprowadzane (w celu zmniejszenia kodu). Istnieje również prosta wersja o nazwie Value (), która zwraca tylko wartość, bez obliczeń lub funkcji. Nawet wartość pochodzi od dostawcy!

    Dlaczego więc takie komplikacje, dlaczego nie możemy po prostu użyć provider i zapomnieć o wszystkim innym? Ma nam pomóc w łatwym pisaniu kodu i lepszej komunikacji. Oraz im bardziej skomplikowana, tym lepsza będzie sprzedaż frameworka.


    • dostawca, który może zwrócić wartość = wartość
    • dostawca, który może po prostu instantiate and return = Factory (+Value)
    • dostawca, który może instantiate + do something = Service (+Factory, + Value)
    • dostawca = musi zawierać właściwość o nazwie $get (+Factory,+ Service,+ Value)

    Angular injection daje nam pierwszą wskazówkę w osiągnięciu ten wniosek.

    "$injector jest używany do pobierania instancji obiektów zdefiniowanych przez provider" nie service, nie factory ale provider.

    A lepszą odpowiedzią byłoby to: "Serwis Angular jest tworzony przez fabrykę usług. Te fabryki usług są funkcjami, które z kolei są tworzone przez dostawcę usług. Usługodawcami są funkcje konstruktorów. Po utworzeniu instancji muszą one zawierać właściwość o nazwie $ get, która przechowuje fabrykę usług funkcja."

    Więc Master provider i injector i wszystko spadnie na swoje miejsce:). W maszynopisie robi się ciekawie, gdy $get może być zaimplementowane w dostawcy poprzez dziedziczenie z IServiceProvider.

     -3
    Author: Blue Clouds,
    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-04-05 13:13:00