it-swarm.com.de

Angular.Service vs Angular.factory

Ich habe sowohl angular.factory () als auch angular.service () gesehen, die zum Deklarieren von Diensten verwendet wurden. Ich kann nicht findenangular.service irgendwo in der offiziellen Dokumentation.

Was ist der Unterschied zwischen den beiden Methoden? Welches sollte für was verwendet werden (vorausgesetzt, sie machen verschiedene Dinge)?

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

Ich hatte Probleme, mich mit diesem Konzept zu beschäftigen, bis ich es mir so vorstellte:

Service: Die Funktion , die Sie schreiben, wird ne - editiert:

  myInjectedService  <----  new myServiceFunction()

Factory: Die Funktion (Konstruktor), die Sie schreiben, wird aufgerufen:

  myInjectedFactory  <---  myFactoryFunction()

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

So schreiben Sie beispielsweise eine Dienstfunktion , 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 verwenden Sie eine Factory-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 verwenden Sie eine Factory-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();

Welches verwenden? ...

Mit beidem können Sie dasselbe erreichen. In einigen Fällen bietet Ihnen die -Factory jedoch ein wenig mehr Flexibilität, um eine Injectable mit einer einfacheren Syntax zu erstellen. Dies liegt daran, dass myInjectedService immer ein Objekt sein muss, myInjectedFactory jedoch ein Objekt, eine Funktionsreferenz oder ein beliebiger Wert sein kann. Wenn Sie beispielsweise einen Service geschrieben haben, um einen Konstruktor zu erstellen (wie im letzten Beispiel oben), muss dieser wie folgt instanziiert werden:

var myShinyNewObject = new myInjectedService.myFunction()

das ist wohl weniger wünschenswert als dies:

var myShinyNewObject = new myInjectedFactory();

(Sie sollten jedoch in erster Linie vorsichtig sein, wenn Sie diese Art von Muster verwenden, da neue - Objekte in Ihren Controllern zu schwer zu verfolgenden Abhängigkeiten führen, die Es ist besser, einen Dienst eine Sammlung von Objekten für Sie verwalten zu lassen, als new() wily-nilly zu verwenden.)


Eins noch, sie sind alle Singletons ...

Beachten Sie auch, dass angular in beiden Fällen bei der Verwaltung eines Singletons hilfreich ist. Unabhängig davon, wo oder wie oft Sie Ihren Dienst oder Ihre Funktion injizieren, erhalten Sie denselben Verweis auf dasselbe Objekt oder dieselbe Funktion. (Mit der Ausnahme, dass eine Factory einfach einen Wert wie eine Zahl oder eine Zeichenfolge zurückgibt. In diesem Fall erhalten Sie immer den gleichen Wert, jedoch keine Referenz.)

1264
Gil Birman

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'));
317
Kirk Strobeck

Hier sind die Hauptunterschiede:

Dienstleistungen

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

Ergebnis: Wenn Sie serviceName als injizierbares Argument deklarieren, erhalten Sie die Instanz einer Funktion , die an module.service übergeben wird.

Verwendung: Kann nützlich sein, um Dienstprogrammfunktionen gemeinsam zu nutzen , die durch einfaches Anhängen von ( ) an die Referenz der injizierten Funktion aufgerufen werden können. Kann auch mit injectedArg.call( this ) oder ähnlichem ausgeführt werden.

Fabriken

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

Ergebnis: Wenn Sie factoryName als injizierbares Argument deklarieren, erhalten Sie den Wert , der durch Aufrufen der an module.factory übergebenen Funktionsreferenz zurückgegeben wird.

Verwendung: Kann nützlich sein, um eine 'class'-Funktion zurückzugeben, die dann neu erstellt werden kann, um Instanzen zu erstellen.

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

Sie können auch die AngularJS-Dokumentation und eine ähnliche Frage zum Stackoverflow verwirrt über Service vs Factory prüfen.

247
Manish Chhabra

TL; DR

1) Wenn Sie ein Factory verwenden, erstellen Sie ein Objekt, fügen ihm 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 Service verwenden, instanziiert Angular es mit dem Schlüsselwort "new" hinter den Kulissen. Aus diesem Grund fügen Sie Eigenschaften zu "this" hinzu, und der Service gibt "this" zurück. Wenn Sie den Dienst an Ihren Controller übergeben, sind diese Eigenschaften auf "this" jetzt auf diesem Controller über Ihren Dienst verfügbar.

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

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



Non TL; DR

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

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

Nun stehen uns alle Eigenschaften, die wir mit "Service" verknüpfen, zur Verfügung, wenn wir "myFactory" an unseren Controller übergeben.

Fügen wir unserer Rückruffunktion nun einige "private" Variablen hinzu. Auf diese kann nicht direkt vom Controller aus zugegriffen werden. Wir werden jedoch einige Get-/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 mit "Service" verknüpfen. Wir erstellen sie lediglich, um sie später entweder zu verwenden oder zu ändern.

  • baseUrl ist die Basis-URL, die die iTunes-API benötigt
  • _artist ist der Künstler, nach dem wir suchen möchten
  • _finalUrl ist die endgültige und vollständig erstellte URL, zu der iTunes aufgerufen wird. makeUrl ist eine Funktion, mit der unsere iTunes-freundliche URL erstellt und zurückgegeben wird.

Nachdem unsere Hilfsvariablen/privaten Variablen und Funktionen vorhanden sind, fügen wir dem Objekt "service" einige Eigenschaften hinzu. Was auch immer wir auf "Service" stellen, wir können es direkt in jedem Controller verwenden, an den wir "myFactory" übergeben.

Wir werden setArtist- und getArtist-Methoden erstellen, die den Künstler einfach zurückgeben oder festlegen. Wir werden auch eine Methode erstellen, die die iTunes-API mit unserer erstellten URL aufruft. Diese Methode wird ein Versprechen zurückgeben, das erfüllt wird, sobald die Daten von der iTunes-API zurückgekehrt sind. Wenn Sie noch nicht viel Erfahrung mit Versprechungen in Angular haben, kann ich Ihnen nur empfehlen, einen tiefen Tauchgang mit ihnen zu machen.

Unten setArtist akzeptiert einen Künstler und ermöglicht es Ihnen, den Künstler einzustellen. getArtist gibt den Künstler zurück, den callItunes zuerst makeUrl () aufruft, um die URL zu erstellen, die wir für unsere $ http-Anfrage verwenden werden. Dann wird ein Versprechungsobjekt erstellt, eine $ http-Anfrage mit unserer endgültigen URL gesendet. Da $ http dann eine Versprechung zurückgibt, können wir nach unserer Anfrage .success oder .error aufrufen. Wir lösen dann unser Versprechen mit den iTunes-Daten ein oder lehnen es mit der Meldung "Es ist ein Fehler aufgetreten" ab.

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 fertig. Wir können jetzt "myFactory" in jeden Controller einfügen und dann unsere Methoden aufrufen, die wir an unser Service-Objekt angehängt haben (setArtist, getArtist und 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);
      })
  }
});

Im obigen Controller wird der Dienst "myFactory" eingefügt. Anschließend legen wir Eigenschaften für unser $ scope-Objekt fest, die aus Daten von "myFactory" stammen. Der einzige heikle Code oben ist, wenn Sie noch nie mit Versprechungen befasst waren. Da callItunes ein Versprechen zurückgibt, können wir die .then () -Methode verwenden und $ scope.data.artistData erst festlegen, 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
Wenn Sie einen Service erstellen, ist es wahrscheinlich das Wichtigste, dass er mit dem Schlüsselwort "new" instanziiert wird. Für Sie JavaScript-Gurus sollte dies einen großen Hinweis auf die Art des Codes geben. Sehen wir uns für diejenigen unter Ihnen, die nur über begrenzte Kenntnisse in JavaScript verfügen, oder für diejenigen, die nicht genau wissen, was das "neue" Schlüsselwort tatsächlich bewirkt, einige JavaScript-Grundlagen an, die uns letztendlich dabei helfen, die Art eines Dienstes zu verstehen.

Um wirklich zu sehen, welche Änderungen beim Aufrufen einer Funktion mit dem Schlüsselwort "new" auftreten, erstellen Sie eine Funktion und rufen Sie sie mit dem Schlüsselwort "new" auf. Anschließend zeigen wir, was der Interpreter tut, wenn das Schlüsselwort "new" angezeigt wird. Die Endergebnisse sind beide gleich.

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.

Fügen wir nun eine Methode zum Prototyp unserer Person hinzu, damit sie für jede Instanz unserer Personen-Klasse verfügbar ist.

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

Da wir nun die Funktion sayName in den Prototyp einfügen, kann jede Instanz von Person die Funktion sayName aufrufen, um den Namen dieser Instanz zu benachrichtigen.

Nachdem wir nun unsere Person-Konstruktorfunktion und unsere sayName-Funktion in ihrem Prototyp haben, erstellen wir eine Instanz von Person und rufen dann die sayName-Funktion auf.

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

Insgesamt sieht der Code zum Erstellen eines Person-Konstruktors, zum Hinzufügen einer Funktion zum Prototyp, zum Erstellen einer Person-Instanz und zum anschließenden Aufrufen der Funktion für den 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'

Schauen wir uns nun an, was tatsächlich passiert, wenn Sie das Schlüsselwort "new" in JavaScript verwenden. Als Erstes sollten Sie bemerken, dass wir nach der Verwendung von "new" in unserem Beispiel eine Methode (sayName) für "tyler" aufrufen können, als wäre es ein Objekt - das liegt daran, dass es so ist. Zuerst wissen wir also, dass unser Person-Konstruktor ein Objekt zurückgibt, ob wir das im Code sehen oder nicht. Zweitens wissen wir, dass das von der Person-Funktion zurückgegebene Objekt bei fehlgeschlagenen Suchen an den Prototyp delegiert werden muss, da sich unsere sayName-Funktion auf dem Prototyp und nicht direkt auf der Person-Instanz befindet. Einfacher ausgedrückt: Wenn wir tyler.sayName () aufrufen, sagt der Interpreter: "OK, ich werde das soeben erstellte" tyler "-Objekt untersuchen, die Funktion sayName suchen und es dann aufrufen. 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 nennen. ".

Im Folgenden finden Sie Code, mit dem Sie überlegen können, was das "neue" Keyword in JavaScript tatsächlich bewirkt. Dies ist im Grunde ein Codebeispiel für den obigen Absatz. Ich habe die "Dolmetscheransicht" oder die Art und Weise festgelegt, wie der Dolmetscher den Code in Notizen sieht.

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 bewirkt, sollte es einfacher sein, einen Service in Angular zu erstellen.

Wenn Sie einen Service erstellen, müssen Sie wissen, dass Services mit dem Schlüsselwort "new" instanziiert sind. Wenn Sie dieses Wissen mit unseren obigen Beispielen kombinieren, sollten Sie jetzt erkennen, dass Sie Ihre Eigenschaften und Methoden direkt mit "this" verknüpfen, das dann vom Service selbst zurückgegeben wird. Sehen wir uns dies in Aktion an.

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 erstellt und delegieren lässt Es ist ein Prototyp, dann senden Sie es für uns zurück, ohne dass wir die Arbeit erledigen müssen.

Lassen Sie uns als Erstes unsere "private" und Hilfsfunktion erstellen. Dies sollte sehr vertraut aussehen, da wir genau dasselbe mit unserer Fabrik gemacht haben. Ich werde hier nicht erklären, was die einzelnen Zeilen tun, da ich dies im Factory-Beispiel getan habe. Wenn Sie verwirrt sind, lesen Sie das Factory-Beispiel 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;
  }
});

Jetzt werden wir alle unsere Methoden, die in unserem Controller verfügbar sind, an "dies" 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 sind setArtist, getArtist und callItunes genau wie in unserer Fabrik auf jedem Controller verfügbar, an den wir myService übergeben. Hier ist der myService-Controller (der fast genau unserem werkseitigen Controller entspricht).

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 ich bereits erwähnt habe, sind Services, sobald Sie wirklich verstanden haben, was „neu“ bedeutet, fast identisch mit Fabriken in Angular.

135
Tyler McGinnis

Der Hinweis ist im Namen

Dienstleistungen und Fabriken ähneln sich. Beide ergeben ein Singleton-Objekt, das in andere Objekte injiziert werden kann, und werden daher häufig austauschbar verwendet.

Sie sollen semantisch verwendet werden, um verschiedene Entwurfsmuster zu implementieren.

Dienste dienen zum Implementieren eines Dienstmusters

Ein Dienstmuster ist eines, bei dem Ihre Anwendung in logisch konsistente Funktionseinheiten unterteilt ist. Ein Beispiel könnte ein API-Accessor oder eine Reihe von Geschäftslogiken sein.

Dies ist in Angular besonders wichtig, da Angular Modelle normalerweise nur JSON-Objekte sind, die von einem Server abgerufen werden.

Hier ist zum Beispiel ein Github-Dienst. Es weiß, wie man mit Github spricht. Es kennt sich mit URLs und Methoden aus. Wir können es in einen Controller einspeisen 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

Fabriken hingegen sollen ein Fabrikmuster implementieren. Ein Factory-Muster, in dem wir eine Factory-Funktion verwenden, um ein Objekt zu generieren. Normalerweise verwenden wir dies zum Erstellen von Modellen. 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 dies folgendermaßen 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 jeden beliebigen Objekttyp zurückgeben, einschließlich einer Konstruktorfunktion, wie wir oben sehen.

Fabriken geben ein Objekt zurück; Dienste sind neu

Ein weiterer technischer Unterschied besteht in der Zusammensetzung von Dienstleistungen und Fabriken. Eine Servicefunktion wird neu erstellt, um das Objekt zu generieren. Eine Factory-Funktion wird aufgerufen und gibt das Objekt zurück.

  • Services 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 zu bauende Objekt verweist.

Um dies zu veranschaulichen, wird hier dasselbe einfache Objekt mit einem Service und einer Factory erstellt:

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

Alle Antworten hier scheinen sich auf Service und Fabrik zu beziehen, und das gilt auch, da genau danach gefragt wurde. Es ist jedoch auch wichtig zu bedenken, dass es mehrere andere gibt, einschließlich provider(), value() und constant().

Der Schlüssel zum Erinnern ist, dass jeder ein Sonderfall des anderen ist. Jeder Sonderfall 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 möchten, sehen Sie, welche Sie in weniger Code ausführen können, was Sie möchten. Hier ist ein Bild, das zeigt, wie ähnlich sie sind:

enter image description here

Eine vollständige schrittweise Aufschlüsselung und eine kurze Beschreibung der Verwendungsmöglichkeiten finden Sie in dem Blog-Beitrag, von dem ich dieses Bild erhalten habe:

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

27
Luis Perez

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;

Bei Diensten ruft Angular die Konstruktorfunktion durch Aufrufen von new auf. 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 in Steuerungen, Ausführungsblöcke, Direktiven usw

  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 eine Initialisierung durch und legen Funktionen offen. Funktionen können auch auf 'this' verweisen, da es mit 'new' 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 um die Nutzung von Fabriken oder Dienstleistungen geht, sind sich beide sehr ähnlich. Sie werden in Controller, Direktiven, Ausführungsblöcke usw. eingefügt und im Client-Code auf nahezu dieselbe Weise verwendet. Sie sind auch beide Singletons - was bedeutet, dass dieselbe Instanz von allen Stellen gemeinsam genutzt wird, an denen der Service/die Fabrik injiziert wird.

Also was solltest du bevorzugen? Entweder eins - sie sind sich so ähnlich, dass die Unterschiede trivial sind. Wenn Sie eine über die andere wählen, müssen Sie nur wissen, wie sie aufgebaut sind, damit Sie sie ordnungsgemäß implementieren können.

23
pixelbits

Ich habe einige Zeit damit verbracht, den Unterschied herauszufinden.

Und ich denke, die Factory-Funktion verwendet das Modul-Pattern und die Service-Funktion das standardmäßige Java Skript-Konstruktor-Pattern.

5
ps.

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

Das Servicemuster macht meiner Meinung nach nicht viel Sinn, da alles, was es macht, genauso einfach mit einer Fabrik gemacht werden kann. Die Ausnahmen könnten sein:

  • Wenn Sie sich aus irgendeinem Grund für den deklarierten Typ Ihres instanziierten Dienstes interessieren - wenn Sie das Dienstmuster verwenden, ist Ihr Konstruktor der Typ des neuen Dienstes.
  • Wenn Sie bereits eine Konstruktorfunktion haben, die Sie an anderer Stelle verwenden und die Sie auch als Service verwenden möchten (obwohl Sie wahrscheinlich nicht viel brauchen, wenn Sie irgendetwas einschleusen möchten!).

Das Dienstmuster ist wahrscheinlich eine etwas angenehmere Möglichkeit, ein neues Objekt aus syntaktischer Sicht zu erstellen, aber es ist auch kostspieliger, es zu instanziieren. Andere haben angegeben, dass angular "new" verwendet, um den Service zu erstellen, aber das ist nicht ganz richtig - das ist nicht möglich, da jeder Servicekonstruktor eine andere Anzahl von Parametern hat. Was angular tatsächlich tut, ist die interne Verwendung des Factory-Musters, um Ihre Konstruktorfunktion einzuschließen. Dann macht es eine clevere Spielerei, um den "neuen" Operator von Javascript zu simulieren, indem es Ihren Konstruktor mit einer variablen Anzahl von injizierbaren Argumenten aufruft - aber Sie können dies weglassen Schritt, wenn Sie nur das Factory-Muster direkt verwenden, wodurch die Effizienz Ihres Codes geringfügig erhöht wird.

2
Dan King