Frage angular.service gegen angular.factory


Ich habe beides gesehen angular.factory () und angular.service () verwendet, um Dienste zu deklarieren; Wie auch immer, ich nicht finden können  angular.service überall in der offiziellen Dokumentation.

Was ist der Unterschied zwischen den beiden Methoden? Welches sollte für was verwendet werden (unter der Annahme, dass sie verschiedene Dinge tun)?


1036
2018-01-14 18:36


Ursprung


Antworten:


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

Ich hatte Mühe, meinen Kopf um dieses Konzept zu wickeln, bis ich es mir auf diese Weise vorstellte:

Bedienung: das Funktion dass du schreibst wird sein Neu-ed:

  myInjectedService  <----  new myServiceFunction()

Fabrik: das Funktion (Konstruktor), den du schreibst, wird sein aufgerufen:

  myInjectedFactory  <---  myFactoryFunction()

Was Sie damit machen, liegt an Ihnen, aber es gibt einige nützliche Muster ...

Wie zum Beispiel ein Bedienung Funktion, um eine öffentliche API verfügbar zu machen:

function myServiceFunction() {
  this.awesomeApi = function(optional) {
    // calculate some stuff
    return awesomeListOfValues;
  }
}
---------------------------------------------------------------------------------
// Injected in your controller
$scope.awesome = myInjectedService.awesomeApi();

Oder mit a Fabrik Funktion, um eine öffentliche API verfügbar zu machen:

function myFactoryFunction() {
  var aPrivateVariable = "yay";

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

  // expose a public API
  return {
    hello: hello
  };
}
---------------------------------------------------------------------------------
// Injected in your controller
$scope.hello = myInjectedFactory.hello();

Oder mit a Fabrik Funktion um einen Konstruktor zurückzugeben:

function myFactoryFunction() {
    return function() {
        var a = 2;
        this.a2 = function() {
            return a*2;
        };
    };
}
---------------------------------------------------------------------------------
// Injected in your controller
var myShinyNewObject = new myInjectedFactory();
$scope.four = myShinyNewObject.a2();

Welcher zu verwenden? ...

Sie können das gleiche mit beiden erreichen. In einigen Fällen jedoch Fabrik gibt Ihnen ein bisschen mehr Flexibilität, um eine injizierbare mit einer einfacheren Syntax zu erstellen. Das liegt daran, dass myInjectedFactory ein Objekt, eine Funktionsreferenz oder ein beliebiger Wert sein kann, während myInjectedFactory immer ein Objekt sein muss. Wenn Sie beispielsweise einen Dienst zum Erstellen eines Konstruktors geschrieben haben (wie im letzten Beispiel oben), müsste er wie folgt instanziiert werden:

var myShinyNewObject = new myInjectedService.myFunction()

das ist wohl weniger wünschenswert als das:

var myShinyNewObject = new myInjectedFactory();

(Aber Sie sollten sich davor hüten, diese Art von Muster zu verwenden, weil NeuObjekte in Ihren Controllern erzeugen schwer nachzuvollziehende Abhängigkeiten, die beim Testen nur schwer nachzuahmen sind. Es ist besser, wenn ein Service eine Sammlung von Objekten für Sie verwaltet, anstatt sie zu verwenden new() witzig-nilly.)


Noch eine Sache, sie sind alle Singletons ...

Denken Sie auch daran, dass eckig Ihnen in beiden Fällen hilft, ein Singleton zu verwalten. Unabhängig davon, wo oder wie oft Sie Ihren Dienst oder Ihre Funktion injizieren, erhalten Sie dieselbe Referenz auf dasselbe Objekt oder dieselbe Funktion. (Mit Ausnahme, wenn eine Fabrik einfach einen Wert wie eine Zahl oder einen String zurückgibt. In diesem Fall erhalten Sie immer den gleichen Wert, aber keine Referenz.)


1248
2018-02-20 06:46



Einfach gesagt ..

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

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

const fullName = { firstName: 'john' };

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

// Factory
const lastNameFactory = (a, b) => 
  Object.assign({}, a, { lastName: b })
console.log(lastNameFactory(fullName, 'doe'));


316
2018-01-08 02:05



Hier sind die wichtigsten Unterschiede:

Dienstleistungen

Syntax: module.service( 'serviceName', function );

Ergebnis: Wenn serviceName als injizierbares Argument deklariert wird, erhalten Sie die Instanz einer Funktion weitergereicht an module.service.

Verwendung: Könnte nützlich sein für Dienstprogrammfunktionen teilen das ist nützlich, um einfach anzuhängen ( ) auf die Referenz der injizierten Funktion. Könnte auch mit ausgeführt werden injectedArg.call( this ) o.ä.

Fabriken

Syntax: module.factory( 'factoryName', function );

Ergebnis: Wenn factoryName als injizierbares Argument deklariert wird, erhalten Sie die Wert, der durch Aufrufen der Funktionsreferenz zurückgegeben wird weitergereicht an module.factory.

Verwendung: Könnte nützlich sein für die Rückgabe eines 'Klasse' Funktion, die dann zum Erstellen von Instanzen neu erstellt werden kann.

Hier ist Beispiel mit Services und Factory. Lesen Sie mehr über AngularJS Service gegen Fabrik.

Sie können auch die AngularJS Dokumentation und ähnliche Frage auf Stackoverflow verwirrt über Service gegen Fabrik.


243
2018-04-09 23:18



TL; DR 

1) Wenn Sie ein Fabrik Sie erstellen ein Objekt, fügen Eigenschaften hinzu und geben dasselbe Objekt zurück. Wenn Sie diese Factory an Ihren Controller übergeben, sind diese Eigenschaften für das Objekt jetzt in diesem Controller über Ihre Factory verfügbar.

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) Wenn Sie verwenden BedienungAngular instanziiert es hinter den Kulissen mit dem Schlüsselwort "new". Aus diesem Grund fügen Sie 'this' Eigenschaften hinzu, und der Dienst gibt 'this' zurück. Wenn Sie den Service an Ihren Controller übergeben, sind diese Eigenschaften für diesen Service nun über diesen Service auf diesem Controller verfügbar.

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

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



Nicht TL; DR

1) Fabrik 
Fabriken sind die beliebteste Methode zum Erstellen und Konfigurieren eines Service. Es gibt wirklich nicht viel mehr als das, was die TL; DR sagte. Sie erstellen einfach ein Objekt, fügen Eigenschaften hinzu und geben dann dasselbe Objekt zurück. Wenn Sie die Fabrik dann an Ihren Controller übergeben, sind diese Eigenschaften für das Objekt jetzt in diesem Controller über Ihre Fabrik verfügbar. Ein ausführlicheres Beispiel ist unten.

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

Nun stehen uns alle Eigenschaften zur Verfügung, die wir an "Service" vergeben, wenn wir "myFactory" in unseren Controller eingeben.

Nun fügen wir unserer Callback-Funktion einige 'private' Variablen hinzu. Diese werden vom Controller nicht direkt zugänglich sein, aber wir werden eventuell einige Getter / Setter-Methoden für "Service" einrichten, um diese "privaten" Variablen bei Bedarf ändern zu können.

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;
});

Hier werden Sie feststellen, dass wir diese Variablen / Funktionen nicht an "Service" anhängen. Wir erstellen sie einfach, um sie später zu verwenden oder zu ändern.

  • baseUrl ist die Basis-URL, die für die iTunes-API erforderlich ist
  • _artist ist der Künstler, den wir suchen möchten
  • _finalUrl ist die finale und vollständig erstellte URL, zu der wir den Anruf bei iTunes machen werden. makeUrl ist eine Funktion, die unsere erstellt und zurückgibt iTunes-freundliche URL

Jetzt, da unsere help / private Variablen und Funktionen vorhanden sind, fügen wir dem Objekt 'service' einige Eigenschaften hinzu. Was auch immer wir "Service" nennen, wir können direkt an jedem Controller arbeiten, an den wir "myFactory" übergeben.

Wir werden die Methoden setArtist und getArtist erstellen, die den Künstler einfach zurückgeben oder setzen. Wir werden auch eine Methode erstellen, die die iTunes API mit unserer erstellten URL aufruft. Diese Methode liefert ein Versprechen, das erfüllt wird, sobald die Daten von der iTunes-API zurückgegeben wurden. Wenn Sie nicht viel Erfahrung mit Versprechungen in Angular gemacht haben, empfehle ich dringend, einen tiefen Tauchgang an ihnen zu machen.

Unten setArtist akzeptiert einen Künstler und erlaubt Ihnen, den Künstler einzustellen. getArtist gibt den Künstler zurück callItunes ruft zuerst makeUrl () auf, um die URL zu erstellen, die wir mit unserer $ http-Anfrage verwenden werden. Dann richtet es ein Zusicherungsobjekt ein, erstellt eine $ http-Anfrage mit unserer abschließenden URL, und weil $ http eine Zusage zurückgibt, können wir nach unserer Anfrage .success oder .error aufrufen. Wir lösen dann unser Versprechen mit den iTunes Daten, oder wir lehnen es mit einer Nachricht ab, die sagt "Es gab einen Fehler".

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;
});

Jetzt ist unsere Fabrik abgeschlossen. Wir sind nun in der Lage, 'myFactory' in einen beliebigen Controller zu injizieren, und dann können wir unsere Methoden aufrufen, die wir an unser Service-Objekt (setArtist, getArtist und callItunes) angehängt haben.

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);
      })
  }
});

Im obigen Controller injizieren wir den Dienst 'myFactory'. Dann setzen wir Eigenschaften für unser $ scope-Objekt, die aus Daten von 'myFactory' stammen. Der einzige knifflige Code oben ist, wenn Sie nie zuvor mit Versprechen gehandelt haben. Da callItunes eine Zusage zurückgibt, können wir die .then () -Methode verwenden und $ scope.data.artistData nur dann setzen, wenn unser Versprechen mit den iTunes-Daten erfüllt ist. Sie werden feststellen, dass unser Controller sehr "dünn" ist. Alle unsere logischen und persistenten Daten befinden sich in unserem Service, nicht in unserem Controller.

2) Service 
Das größte Problem beim Erstellen eines Service ist vielleicht, dass er mit dem neuen Keyword instanziiert wird. Für Sie JavaScript-Gurus sollte dies einen großen Hinweis auf die Art des Codes geben. Für diejenigen unter Ihnen, die einen eingeschränkten JavaScript-Hintergrund haben oder für diejenigen, die mit dem "neuen" Schlüsselwort nicht vertraut sind, lassen Sie uns ein paar Grundlagen zu JavaScript lesen, die uns helfen, die Natur eines Dienstes zu verstehen.

Um wirklich die Änderungen zu sehen, die beim Aufruf einer Funktion mit dem Schlüsselwort 'new' auftreten, erstellen wir eine Funktion und rufen sie mit dem Schlüsselwort 'new' auf. Dann zeigen wir, was der Interpreter tut, wenn er das Schlüsselwort 'new' sieht. Die Endergebnisse werden beide gleich sein.

Zuerst erstellen wir unseren Konstruktor.

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

Dies ist eine typische JavaScript-Konstruktorfunktion. Wenn wir nun die Funktion Person mit dem Schlüsselwort 'new' aufrufen, wird 'this' an das neu erstellte Objekt gebunden.

Nun fügen wir dem Prototyp unserer Person eine Methode hinzu, so dass sie für jede Instanz unserer "Klasse" verfügbar ist.

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

Da wir nun die Funktion sayName auf den Prototyp anwenden, kann jede Instanz von Person die Funktion sayName aufrufen, um den Namen dieser Instanz zu melden.

Jetzt, wo wir unsere Person-Konstruktorfunktion und unsere sayName-Funktion für ihren Prototyp haben, erstellen wir eigentlich eine Instanz von Person und rufen dann die sayName-Funktion auf.

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

Alles in allem sieht der Code zum Erstellen eines Person-Konstruktors, Hinzufügen einer Funktion zu seinem Prototyp, Erstellen einer Person-Instanz und anschließendem Aufruf der Funktion an seinem Prototyp folgendermaßen aus.

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'

Sehen wir uns jetzt an, was tatsächlich passiert, wenn Sie das Schlüsselwort "new" in JavaScript verwenden. Das erste, was Sie beachten sollten, ist, dass wir, nachdem wir in unserem Beispiel 'neu' verwendet haben, eine Methode (sayName) auf 'tyler' aufrufen können, als ob es ein Objekt wäre - das liegt daran, dass es so ist. Zuerst wissen wir, dass unser Person-Konstruktor ein Objekt zurückgibt, unabhängig davon, ob wir das im Code sehen oder nicht. Zweitens wissen wir, dass die Funktion sayName auf dem Prototyp und nicht direkt auf der Person-Instanz liegt. Das Objekt, das die Person-Funktion zurückgibt, muss bei fehlgeschlagenen Suchvorgängen an ihren Prototyp delegieren. Einfach ausgedrückt, wenn wir tyler.sayName () aufrufen, sagt der Interpreter: "OK, ich werde auf das 'tyler' Objekt schauen, das wir gerade erstellt haben, suchen Sie die sayName Funktion und rufen Sie sie dann auf. Moment mal, ich sehe es hier nicht - alles was ich sehe ist Name und Alter, lass mich den Prototyp überprüfen. Ja, es sieht so aus, als wäre es auf dem Prototyp, lass es mich so nennen. "

Im Folgenden finden Sie einen Code, wie Sie darüber nachdenken können, was das "neue" Keyword tatsächlich in JavaScript bewirkt. Es ist im Grunde ein Codebeispiel für den obigen Absatz. Ich habe die 'Interpreter-Ansicht' oder die Art, wie der Interpreter den Code in den Notizen sieht, gesetzt.

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

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

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

  //return this;
}

Wenn Sie nun wissen, was das "neue" Schlüsselwort in JavaScript wirklich bedeutet, sollte das Erstellen eines Dienstes in Angular einfacher zu verstehen sein.

Beim Erstellen eines Service ist es am wichtigsten zu wissen, dass Services mit dem Schlüsselwort "new" instanziiert werden. Wenn Sie dieses Wissen mit unseren obigen Beispielen kombinieren, sollten Sie nun erkennen, dass Sie Ihre Eigenschaften und Methoden direkt an "diese" anhängen, die dann vom Dienst selbst zurückgegeben werden. Werfen wir einen Blick darauf in Aktion.

Im Gegensatz zu dem, was wir ursprünglich mit dem Factory-Beispiel gemacht haben, müssen wir kein Objekt erstellen und dann dieses Objekt zurückgeben, da wir, wie schon oft erwähnt, das Schlüsselwort 'new' verwendet haben, damit der Interpreter dieses Objekt erstellen kann es ist ein Prototyp, dann gib es für uns zurück, ohne dass wir die Arbeit machen müssen.

Lassen Sie uns als Erstes unsere "private" und Hilfsfunktion erstellen. Dies sollte sehr vertraut sein, da wir genau das gleiche mit unserer Fabrik gemacht haben. Ich werde nicht erklären, was jede Zeile hier macht, weil ich das im Fabrikbeispiel getan habe. Wenn Sie verwirrt sind, lesen Sie das Fabrikbeispiel erneut.

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;
  }
});

Nun werden wir alle unsere Methoden, die in unserem Controller verfügbar sein werden, an "das" anhängen.

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;
  }

});

Jetzt, genau wie in unserer Fabrik, werden setArtist, getArtist und callItunes in jedem Controller verfügbar sein, an den myService übergeben wird. Hier ist der myService-Controller (der fast genau so wie unser Factory-Controller ist).

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);
      })
  }
});

Wie bereits erwähnt, sind Dienste, sobald Sie wirklich verstehen, was "neu" ist, fast identisch mit Fabriken in Angular.


134
2018-05-14 16:14



Der Hinweis ist im Namen

Dienstleistungen und Fabriken sind einander ähnlich. Beide ergeben ein Singleton-Objekt, das in andere Objekte injiziert werden kann und daher häufig synonym verwendet wird.

Sie sollen semantisch zur Implementierung unterschiedlicher Entwurfsmuster verwendet werden.

Dienste dienen zum Implementieren eines Dienstmusters

Ein Servicemuster ist eines, in dem Ihre Anwendung in logisch konsistente Funktionseinheiten aufgeteilt ist. Ein Beispiel könnte ein API-Accessor oder eine Geschäftslogik sein.

Dies ist besonders wichtig in Angular, da Angular-Modelle in der Regel nur JSON-Objekte sind, die von einem Server stammen. Daher benötigen wir einen Ort, an den wir unsere Geschäftslogik übertragen können.

Hier ist zum Beispiel ein Github-Service. Es weiß, wie man mit Github spricht. Es kennt URLs und Methoden. Wir können es in einen Controller injizieren und es wird ein Versprechen generieren und zurückgeben.

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

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

Fabriken implementieren ein Fabrikmuster

Auf der anderen Seite sollen Fabriken ein Fabrikmuster implementieren. Ein Factory-Muster in einem, in dem wir eine Factory-Funktion verwenden, um ein Objekt zu generieren. In der Regel können wir dies zum Erstellen von Modellen verwenden. Hier ist eine Factory, die einen Author-Konstruktor zurückgibt:

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

Wir würden das wie folgt nutzen:

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

Beachten Sie, dass Fabriken auch Singletons zurückgeben.

Fabriken können einen Konstruktor zurückgeben

Da eine Factory einfach ein Objekt zurückgibt, kann sie einen beliebigen Objekttyp zurückgeben, einschließlich einer Konstruktorfunktion (siehe oben).

Fabriken geben ein Objekt zurück; Dienste sind umsetzbar

Ein weiterer technischer Unterschied besteht in der Art und Weise, wie Dienstleistungen und Fabriken zusammengesetzt sind. Eine Service-Funktion wird neu generiert, um das Objekt zu generieren. Eine Factory-Funktion wird aufgerufen und gibt das Objekt zurück.

  • Dienste sind neue Konstruktoren.
  • Fabriken werden einfach aufgerufen und geben ein Objekt zurück.

Dies bedeutet, dass wir in einem Service an "this" anhängen, das im Kontext eines Konstruktors auf das Objekt im Aufbau zeigt.

Um dies zu veranschaulichen, ist hier das gleiche einfache Objekt, das mit einem Service und einer Factory erstellt wurde:

angular.module('app', [])
  .service('helloService', function() {
    this.sayHello = function() {
      return "Hello!";
    }
  })
  .factory('helloFactory', function() {
    return {
      sayHello: function() {
        return "Hello!";
      }
    }
  });

33
2017-12-18 11:48



app.factory ('fn', fn) vs. App-Service ('fn', fn)

Konstruktion

Bei Fabriken ruft Angular die Funktion auf, um das Ergebnis zu erhalten. Es ist das Ergebnis, das zwischengespeichert und injiziert wird.

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

Mit Diensten ruft Angular die Konstruktorfunktion durch Aufruf auf Neu. Die konstruierte Funktion wird zwischengespeichert und injiziert.

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

Implementierung

Fabriken geben normalerweise ein Objektliteral zurück, weil der Rückgabewert ist was wird in Controller injiziert, Blöcke, Anweisungen, etc

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

Servicefunktionen geben normalerweise nichts zurück. Stattdessen führen sie Initialisierungs- und Expose-Funktionen aus. Funktionen können auch auf 'dieses' verweisen, da es mit 'neu' erstellt wurde.

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

Fazit

Wenn es darum geht, Fabriken oder Dienstleistungen zu nutzen, sind sie sich sehr ähnlich. Sie werden in Controller, Direktiven, Run-Block usw. eingefügt und im Client-Code auf die gleiche Weise verwendet. Sie sind auch beide Singletons - was bedeutet, dass die gleiche Instanz zwischen allen Orten geteilt wird, an denen der Service / die Fabrik injiziert wird.

Also, was solltest du bevorzugen? Entweder man - sie sind so ähnlich, dass die Unterschiede trivial sind. Wenn Sie sich für eines entscheiden, müssen Sie sich nur darüber im Klaren sein, wie sie aufgebaut sind, damit Sie sie richtig implementieren können.


23
2018-06-27 00:17



Alle Antworten hier scheinen um Service und Fabrik herum zu gehen, und das ist gültig, weil das gefragt wurde. Aber es ist auch wichtig zu beachten, dass es mehrere andere gibt provider(), value(), und constant().

Der Schlüssel zum Erinnern ist, dass jeder ein spezieller Fall des anderen ist. Jeder Spezialfall in der Kette ermöglicht es Ihnen, dasselbe mit weniger Code zu tun. Jeder hat auch eine zusätzliche Einschränkung.

Um zu entscheiden, wann Sie welche verwenden, sehen Sie nur, welche Sie in weniger Code machen können, was Sie wollen. Hier ist ein Bild, das zeigt, wie ähnlich sie sind:

enter image description here

Für eine vollständige Schritt-für-Schritt-Aufschlüsselung und eine schnelle Referenz, wann Sie beide verwenden sollten, können Sie den Blog-Post besuchen, von dem ich dieses Bild bekommen habe:

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


23
2017-12-10 12:55



Ich habe einige Zeit damit verbracht, den Unterschied herauszufinden.

Und ich denke, die Factory-Funktion verwendet die Modulmuster und Service-Funktion verwendet das Standard-Java-Skript-Konstruktor-Muster.


5
2018-03-10 15:04



Das Factory-Muster ist flexibler, da es Funktionen und Werte sowie Objekte zurückgeben kann.

Es gibt nicht viel Sinn in der Service-Muster IMHO, wie alles, was Sie tun können Sie genauso leicht mit einer Fabrik tun. Die Ausnahmen könnten sein:

  • Wenn Sie den deklarierten Typ Ihres instanziierten Dienstes aus irgendeinem Grund interessieren - wenn Sie das Dienstmuster verwenden, ist Ihr Konstruktor der Typ des neuen Dienstes.
  • Wenn Sie bereits eine Konstruktorfunktion haben, die Sie woanders verwenden, die Sie auch als Dienst verwenden möchten (obwohl es wahrscheinlich nicht viel nutzt, wenn Sie etwas hinein injizieren wollen!).

Wohlgemerkt ist das Servicemuster a leicht Eine bessere Möglichkeit, ein neues Objekt unter dem Gesichtspunkt der Syntax zu erstellen, aber es ist auch kostspieliger, es zu instanziieren. Andere haben angegeben, dass eckig "neu" verwendet, um den Dienst zu erstellen, aber dies ist nicht ganz richtig - es ist nicht in der Lage, dies zu tun, da jeder Dienstkonstruktor eine andere Anzahl von Parametern hat. Der Winkel, der tatsächlich verwendet wird, verwendet intern das Factory-Muster, um die Konstruktorfunktion zu umbrechen. Dann macht es ein paar clevere Jiggery Pokery zu simulieren javascript's "new" -Operator, der seinen Konstruktor mit einer variablen Anzahl injizierbarer Argumente aufruft - aber Sie können diesen Schritt weglassen, wenn Sie nur das Factory-Muster direkt verwenden, wodurch die Effizienz Ihres Codes sehr leicht erhöht wird.


2
2017-08-06 14:54