299

ここで我慢してください。私は次のような他の答えがあることを知っています: AngularJS: Service vs provider vs factory

ただし、いつファクトリよりもサービスを使用するかはまだわかりません。

私が言えることから、ファクトリは、複数のコントローラーから呼び出すことができる「共通の」関数を作成するために一般的に使用されます:共通のコントローラー関数の作成

Angular のドキュメントは、サービスよりも工場を好むようです。彼らは factory を使用するときに「サービス」とさえ呼んでいますが、これはさらに混乱を招きます。http://docs.angularjs.org/guide/dev_guide.services.creating_services

では、いつサービスを利用するのでしょうか?

サービスでしかできないこと、またはもっと簡単にできることはありますか?

舞台裏で何か違うことはありますか?パフォーマンス/メモリの違いは?

これが例です。宣言の方法を除けば、それらは同じように見えますが、なぜ一方と他方を行うのかわかりません。http://jsfiddle.net/uEpkE/

更新:トーマスの回答から、サービスはより単純なロジック用であり、ファクトリはプライベート メソッドを使用したより複雑なロジック用であることを暗示しているように思われるため、以下のフィドル コードを更新しましたが、どちらもプライベート関数をサポートできるようですか?

myApp.factory('fooFactory', function() {
    var fooVar;
    var addHi = function(foo){ fooVar = 'Hi '+foo; }

    return {
        setFoobar: function(foo){
            addHi(foo);
        },
        getFoobar:function(){
            return fooVar;
        }
    };
});
myApp.service('fooService', function() {
    var fooVar;
    var addHi = function(foo){ fooVar = 'Hi '+foo;}

    this.setFoobar = function(foo){
        addHi(foo);
    }
    this.getFoobar = function(){
        return fooVar;
    }
});

function MyCtrl($scope, fooService, fooFactory) {
    fooFactory.setFoobar("fooFactory");
    fooService.setFoobar("fooService");
    //foobars = "Hi fooFactory, Hi fooService"
    $scope.foobars = [
        fooFactory.getFoobar(),
        fooService.getFoobar()
    ];
}
4

9 に答える 9

283

説明

ここにはさまざまなものがあります:

初め:

  • サービスを使用すると、関数のインスタンス(" this" キーワード) が取得されます。
  • ファクトリを使用すると 、関数参照(ファクトリの return ステートメント)を呼び出すことによって返される値を取得できます。

参照: angular.service と angular.factory

2番:

AngularJS のすべてのプロバイダー (値、定数、サービス、ファクトリー) はシングルトンであることに注意してください。

三番:

どちらか一方 (サービスまたはファクトリ) を使用することは、コード スタイルに関するものです。しかし、AngularJS での一般的な方法はfactoryを使用することです。

なんで ?

「ファクトリ メソッドは、オブジェクトを AngularJS 依存性注入システムに取り込む最も一般的な 方法です。非常に柔軟で、洗練された作成ロジックを含めることができます。ファクトリは通常の関数であるため、新しいレキシカル スコープを利用して「プライベート」をシミュレートすることもできます。 "変数。特定のサービスの実装の詳細を隠すことができるので、これは非常に便利です。"

(参照: http://www.amazon.com/Mastering-Web-Application-Development-AngularJS/dp/1782161821 )。


使用法

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

Factory :インスタンスを作成するために new`ed できる「クラス」関数を返すのに役立つ可能性があります。

したがって、サービスに複雑なロジックがあり、この複雑さを公開したくない場合は、ファクトリを使用してください。

それ以外の場合、サービスのインスタンスを返したい場合は、単に service を使用してください。

しかし、時間の経過とともに、80% のケースで factory を使用することがわかるでしょう。

詳細: http://blog.manishchhabra.com/2013/09/angularjs-service-vs-factory-with-example/


アップデート :

ここの優れた投稿: http://iffycan.blogspot.com.ar/2013/05/angular-service-or-factory.html

「関数を通常の function のように呼び出したい場合はfactoryを使用 してください。関数を new 演算子でインスタンス化する場合は service を使用してください。違いがわからない場合は factory を使用してください。」


アップデート :

AngularJS チームが作業を行い、説明を行います: http://docs.angularjs.org/guide/providers

そして、このページから:

「Factory と Service は最も一般的に使用されるレシピです。それらの唯一の違いは、Service レシピがカスタム タイプのオブジェクトに対してより適切に機能することです。一方、Factory は JavaScript プリミティブと関数を生成できます。」

于 2013-09-22T08:31:27.630 に答える
112

allernhwkimは当初、この質問に対する回答を彼のブログにリンクして投稿しましたが、モデレーターによって削除されました。これは私が見つけた唯一の投稿であり、サービス、プロバイダー、およびファクトリーで同じことを行う方法を説明するだけでなく、ファクトリーではできないことをプロバイダーで行う方法についても説明しています。サービスではできない工場。

彼のブログから直接:

app.service('CarService', function() {
   this.dealer="Bad";
    this.numCylinder = 4;
});

app.factory('CarFactory', function() {
    return function(numCylinder) {
      this.dealer="Bad";
        this.numCylinder = numCylinder
    };
});

app.provider('CarProvider', function() {
    this.dealerName = 'Bad';
    this.$get = function() {
        return function(numCylinder) {
            this.numCylinder = numCylinder;
            this.dealer = this.dealerName;
        }
    };
    this.setDealerName = function(str) {
      this.dealerName = str;
    }      
});

これは、CarService が常に 4 気筒の車を生成する方法を示しています。個々の車に対して変更することはできません。一方、CarFactory は関数を返すため、new CarFactoryその車に固有のシリンダー数を渡して、コントローラーで実行できます。new CarServiceCarService は関数ではなくオブジェクトであるため、できません。

ファクトリが次のように機能しない理由:

app.factory('CarFactory', function(numCylinder) {
      this.dealer="Bad";
      this.numCylinder = numCylinder
});

そして、インスタンス化する関数を自動的に返します。これは、これを行うことができないためです (prototype/etc に何かを追加する):

app.factory('CarFactory', function() {
    function Car(numCylinder) {
        this.dealer="Bad";
        this.numCylinder = numCylinder
    };
    Car.prototype.breakCylinder = function() {
        this.numCylinder -= 1;
    };
    return Car;
});

文字通り車を生産する工場である様子をご覧ください。

彼のブログからの結論はかなり良いです:

結論は、

---------------------------------------------------  
| Provider| Singleton| Instantiable | Configurable|
---------------------------------------------------  
| Factory | Yes      | Yes          | No          |
---------------------------------------------------  
| Service | Yes      | No           | No          |
---------------------------------------------------  
| Provider| Yes      | Yes          | Yes         |       
---------------------------------------------------  
  1. {foo;1, bar:2} など、ハッシュなどの単純なオブジェクトだけが必要な場合は、Service を使用します。コーディングは簡単ですが、インスタンス化することはできません。

  2. オブジェクトをインスタンス化する必要がある場合は、Factory を使用します。つまり、new Customer()、new Comment() などです。

  3. 構成する必要がある場合は、プロバイダーを使用します。つまり、テスト URL、QA URL、本番 URL です。

ファクトリにオブジェクトを返すだけであることがわかった場合は、おそらくサービスを使用する必要があります。

これをしないでください:

app.factory('CarFactory', function() {
    return {
        numCylinder: 4
    };
});

代わりにサービスを使用してください:

app.service('CarService', function() {
    this.numCylinder = 4;
});
于 2014-12-03T04:52:28.980 に答える
21

これらすべてのプロバイダーの概念は、最初に表示されたものよりもはるかに単純です。プロバイダーを分析してさまざまな部分を引き出すと、非常に明確になります。

簡単に言うと、これらのプロバイダーのそれぞれは、次の順序で、他のプロバイダーの特殊化されたバージョンです: provider> factory> value/ constant/ service.

プロバイダーができることを実行している限り、プロバイダーをチェーンのさらに下で使用できるため、コードの記述が少なくて済みます。期待どおりの結果が得られない場合は、チェーンを上っていくことができ、コードをさらに記述する必要があります。

この画像は私が何を意味するかを示しています。この画像では、プロバイダーのコードが表示されます。強調表示された部分は、プロバイダーのどの部分を使用してファクトリや値などを作成できるかを示しています。

AngularJS プロバイダー、ファクトリー、サービスなどはすべて同じものです
(ソース: Simplygoodcode.com )

画像を取得したブログ投稿の詳細と例については、http ://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory-in-angularjs/ にアクセスしてください。

于 2015-11-19T19:54:55.717 に答える
2

すべてのサービスとファクトリがシングルトンであると言われても、私は 100% 同意しません。工場はシングルトンではないと思います。これが私の答えのポイントです。すべてのコンポーネント (サービス/ファクトリー) を定義する名前について本当に考えます。

ファクトリはシングルトンではないため、注入時に好きなだけ作成できるため、オブジェクトのファクトリのように機能します。ドメインのエンティティのファクトリを作成し、モデルのオブジェクトのようなこのオブジェクトをより快適に操作できます。複数のオブジェクトを取得すると、それらをこのオブジェクトにマップすることができ、DDBB と AngularJs モデルの間の一種の別のレイヤーとして機能することができます。

一方、サービスはシングルトンであるため、1 つの種類しか作成できず、作成できない可能性もありますが、コントローラーに注入するときに 1 つのインスタンスしかないため、サービスはより一般的なサービス (残りの呼び出し、機能など) を提供します。コントローラーに。

概念的には、サービスがサービスを提供するように考えることができ、ファクトリはクラスの複数のインスタンス (オブジェクト) を作成できます。

于 2015-10-23T10:10:52.877 に答える
2

サービスと比較して、ファクトリができないこと、またはより優れていることは何もありません。そしてその逆。ファクトリーはもっと人気があるようです。その理由は、プライベート/パブリック メンバーを処理する際の利便性です。この点で、サービスはより不器用になります。Service をコーディングするとき、「this」キーワードを使用してオブジェクト メンバーをパブリックにする傾向があり、それらのパブリック メンバーがプライベート メソッド (つまり、内部関数) から見えないことが突然わかる場合があります。

var Service = function(){

  //public
  this.age = 13;

  //private
  function getAge(){

    return this.age; //private does not see public

  }

  console.log("age: " + getAge());

};

var s = new Service(); //prints 'age: undefined'

Angular は「new」キーワードを使用してサービスを作成するため、Angular がコントローラーに渡すインスタンスには同じ欠点があります。もちろん、これ/あれを使用して問題を解決できます。

var Service = function(){

  var that = this;

  //public
  this.age = 13;

  //private
  function getAge(){

    return that.age;

  }

  console.log("age: " + getAge());

};

var s = new Service();// prints 'age: 13'  

しかし、大きい Service 定数を使用すると、this\that-ing によってコードが読みにくくなります。さらに、サービス プロトタイプはプライベート メンバーを認識しません。パブリックのみが利用可能です。

var Service = function(){

  var name = "George";

};

Service.prototype.getName = function(){

  return this.name; //will not see a private member

};

var s = new Service();
console.log("name: " + s.getName());//prints 'name: undefined'

まとめると、Factory を使用する方が便利です。Factory にはこれらの欠点がありません。デフォルトで使用することをお勧めします。

于 2015-07-18T11:01:46.697 に答える
0

サービス

構文: module.service( 'serviceName', function ); 結果: serviceName を注入可能な引数として宣言すると、module.service に渡される実際の関数参照が提供されます。

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

工場

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

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

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

プロバイダ

構文: module.provider( 'providerName', function );

結果: providerName を注入可能な引数として宣言すると、module.provider に渡された関数参照の $get メソッドを呼び出すことによって返される値が提供されます。

使用法: インスタンスを作成するために新しく作成できる「クラス」関数を返すのに役立つ可能性がありますが、注入される前に何らかの構成が必要です。プロジェクト間で再利用可能なクラスにおそらく役立つでしょうか? これについてはまだちょっとぼんやりしています。

于 2015-04-27T13:18:15.193 に答える