1078

サービスを宣言するためにangular.factory ()angular.service( )の両方が使用されているのを見てきました。ただし、公式ドキュメントのどこにも見つかりません。 angular.service

2つの方法の違いは何ですか?
どちらを何に使用する必要がありますか (異なることを行うと仮定して)?

4

9 に答える 9

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

このように自分自身に置くまで、この概念に頭を悩ませました。

Service :あなたが書く関数は新しいものになります-ed:

  myInjectedService  <----  new myServiceFunction()

Factory : 作成した関数(コンストラクター) が呼び出されます

  myInjectedFactory  <---  myFactoryFunction()

それをどうするかはあなた次第ですが、いくつかの便利なパターンがあります...

パブリック API を公開するサービス関数の作成など:

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

または、ファクトリ関数を使用してパブリック API を公開します。

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

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

または、ファクトリー関数を使用してコンストラクターを返します。

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

どっちを使う?...

両方で同じことを達成できます。ただし、場合によっては、ファクトリを使用すると、より単純な構文で注入可能なものを作成する柔軟性が少し高くなります。これは、myInjectedService は常にオブジェクトでなければならないのに対し、myInjectedFactory はオブジェクト、関数参照、または任意の値である可能性があるためです。たとえば、(上記の最後の例のように) コンストラクターを作成するサービスを作成した場合、次のようにインスタンス化する必要があります。

var myShinyNewObject = new myInjectedService.myFunction()

これは間違いなくこれよりも望ましくありません。

var myShinyNewObject = new myInjectedFactory();

(しかし、最初からこのタイプのパターンを使用することには注意が必要です。なぜなら、コントローラー内の新しい-ing オブジェクトは、テスト用にモックするのが難しい、追跡しにくい依存関係を作成するからです。new()wily-nillyを使用しないでください。)


もう1つ、それらはすべてシングルトンです...

また、どちらの場合も、角度はシングルトンの管理に役立つことに注意してください。サービスまたは関数を注入する場所や回数に関係なく、同じオブジェクトまたは関数への同じ参照を取得します。(ファクトリが単に数値や文字列などの値を返す場合を除きます。その場合、常に同じ値を取得しますが、参照は取得しません。)

于 2014-02-20T06:46:54.690 に答える
319

簡単に言えば ..

const user = {
  firstName: 'john'
};

// Factory
const addLastNameFactory = (user, lastName) => ({
  ...user,
  lastName,
});

console.log(addLastNameFactory(user, 'doe'));

// Service
const addLastNameService = (user, lastName) => {
  user.lastName = lastName; // BAD! Mutation
  return user;
};

console.log(addLastNameService(user, 'doe'));

于 2014-01-08T02:05:28.027 に答える
247

主な違いは次のとおりです。

サービス

構文:module.service( 'serviceName', function );

結果: serviceName を注入可能な引数として宣言すると、 に渡される関数のインスタンスmodule.serviceが提供されます。

使用法:注入された関数参照に追加するだけで呼び出すのに役立つユーティリティ関数を共有するのに役立ちます。または同様のもの( )で実行することもできます。injectedArg.call( this )

工場

構文:module.factory( 'factoryName', function );

結果: factoryName を注入可能な引数として宣言すると、 に渡された関数参照を呼び出すことによって返される値module.factoryが提供されます。

使用法:インスタンスを作成するために new できる「クラス」関数を返すのに役立ちます。

services と factory を使用した例を次に示します。AngularJS Service と Factoryの詳細をお読みください。

AngularJS のドキュメントと、 service と factory について混乱している stackoverflow に関する同様の質問を確認することもできます。

于 2013-04-09T23:18:52.037 に答える
35

ヒントは名前にあります

サービスと工場は似ています。どちらも、他のオブジェクトに注入できるシングルトン オブジェクトを生成するため、多くの場合、同じ意味で使用されます。

これらは、さまざまな設計パターンを実装するために意味的に使用することを目的としています。

サービスはサービス パターンを実装するためのものです

サービス パターンとは、アプリケーションを論理的に一貫した機能単位に分割するパターンです。例として、API アクセサーや一連のビジネス ロジックが挙げられます。

これは Angular では特に重要です。なぜなら、Angular モデルは通常、サーバーから取得された単なる JSON オブジェクトであり、ビジネス ロジックを配置する場所が必要だからです。

たとえば、Github サービスを次に示します。Github との対話方法を知っています。URLとメソッドについて知っています。これをコントローラーに注入すると、Promise が生成されて返されます。

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

ファクトリはファクトリ パターンを実装します

一方、ファクトリは、ファクトリ パターンを実装することを目的としています。ファクトリ関数を使用してオブジェクトを生成するファクトリ パターン。通常、モデルの構築にこれを使用します。Author コンストラクタを返すファクトリは次のとおりです。

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

これを次のように使用します。

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

ファクトリもシングルトンを返すことに注意してください。

ファクトリはコンストラクタを返すことができます

ファクトリは単純にオブジェクトを返すため、上記のように、コンストラクター関数を含め、任意の型のオブジェクトを返すことができます。

ファクトリはオブジェクトを返します。サービスは新規可能です

もう 1 つの技術的な違いは、サービスとファクトリの構成方法にあります。オブジェクトを生成するために、サービス関数が新しく作成されます。ファクトリ関数が呼び出され、オブジェクトが返されます。

  • サービスは newable コンストラクターです。
  • ファクトリは単純に呼び出され、オブジェクトを返します。

これは、サービスでは、コンストラクターのコンテキストで構築中のオブジェクトを指す「this」に追加することを意味します。

これを説明するために、サービスとファクトリを使用して作成された同じ単純なオブジェクトを次に示します。

angular.module('app', [])
  .service('helloService', function() {
    this.sayHello = function() {
      return "Hello!";
    }
  })
  .factory('helloFactory', function() {
    return {
      sayHello: function() {
        return "Hello!";
      }
    }
  });
于 2014-12-18T11:48:51.320 に答える
28

ここでのすべての回答は、サービスと工場に関するものであるように思われます。ただし、 、 、などprovider()、他にもいくつかあることを覚えておくことも重要です。value()constant()

覚えておくべき重要な点は、それぞれが他の特殊なケースであるということです。チェーンの各特殊ケースにより、少ないコードで同じことを実行できます。それぞれに追加の制限もあります。

どちらをいつ使用するかを決定するには、どちらを使用すると、より少ないコードで必要なことを実行できるかがわかります。これらがどれほど似ているかを示す画像を次に示します。

ここに画像の説明を入力

完全なステップバイステップの内訳と、それぞれをいつ使用するかのクイックリファレンスについては、この画像を入手したブログ投稿にアクセスできます。

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

于 2015-12-10T12:55:34.330 に答える
24

app.factory('fn', fn) と app.service('fn',fn)

工事

ファクトリを使用すると、Angular は関数を呼び出して結果を取得します。キャッシュされて注入されるのは結果です。

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

サービスを使用すると、Angular はnewを呼び出してコンストラクター関数を呼び出します。構築された関数はキャッシュされ、注入されます。

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

実装

ファクトリは通常、オブジェクト リテラルを返します。これは、戻り値コントローラー、実行ブロック、ディレクティブなどに注入されたものであるためです。

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

通常、サービス関数は何も返しません。代わりに、初期化を実行し、関数を公開します。「this」は「new」を使用して構築されているため、関数も「this」を参照できます。

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

結論

ファクトリまたはサービスの使用に関しては、どちらも非常に似ています。それらはコントローラー、ディレクティブ、実行ブロックなどに挿入され、ほとんど同じ方法でクライアント コードで使用されます。どちらもシングルトンです。つまり、サービス/ファクトリが注入されるすべての場所で同じインスタンスが共有されます。

それで、あなたはどちらを好むべきですか?いずれか - それらは非常に似ているため、違いは些細なことです。どちらかを選択する場合は、適切に実装できるように、それらがどのように構築されているかに注意してください。

于 2014-06-27T00:17:34.073 に答える
5

私は違いを理解しようとしてしばらく時間を費やしました。

また、ファクトリ関数はモジュール パターンを使用し、サービス関数は標準の Java スクリプト コンストラクタ パターンを使用すると思います。

于 2015-03-10T15:04:24.847 に答える
2

ファクトリ パターンは、関数と値、およびオブジェクトを返すことができるため、より柔軟です。

サービス パターン IMHO にはあまり意味がありません。それが行うすべてのことは、ファクトリと同じように簡単に行うことができます。例外は次のとおりです。

  • なんらかの理由でインスタンス化されたサービスの宣言された型を気にする場合 - サービス パターンを使用する場合、コンストラクターは新しいサービスの型になります。
  • 他の場所で使用しているコンストラクター関数を既に持っている場合は、それをサービスとしても使用します (ただし、何かを注入したい場合はおそらくあまり使用されません!)。

おそらく、サービス パターンは、構文の観点から新しいオブジェクトを作成するためのわずかに優れた方法ですが、インスタンス化のコストも高くなります。angular は "new" を使用してサービスを作成することを他の人が示していますが、これは完全に真実ではありません。すべてのサービス コンストラクターが異なる数のパラメーターを持っているため、それを行うことはできません。angular が実際に行うことは、ファクトリ パターンを内部で使用してコンストラクタ関数をラップすることです。次に、javascript の "new" 演算子をシミュレートするために巧妙なジグリー ポーキーを実行し、可変数の注入可能な引数を使用してコンストラクターを呼び出します。ただし、ファクトリ パターンを直接使用するだけの場合は、この手順を省略できます。コード。

于 2015-08-06T14:54:33.470 に答える