web-dev-qa-db-ja.com

AngularJS:いつ工場の代わりにサービスを利用するか

私と一緒にここにいてください。私はそのような他の答えがあることを知っています。 AngularJS:サービスvsプロバイダvsファクトリ

しかし、いつでも工場でサービスを利用するのかわかりません。

私が言うことができるものからファクトリは一般的に複数のコントローラによって呼び出されることができる「一般的な」機能を作成するために使用されます: 一般的なコントローラ機能の作成

Angularドキュメントはファクトリよりサービスよりも好むようです。彼らは彼らが工場を使うとき「サービス」さえ参照します。 http://docs.angularjs.org/guide/dev_guide.services.creating_services

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

サービスを利用した場合にのみ可能またはそれ以上に簡単なことがありますか。

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

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

更新:Thomasの答えから、サービスは単純なロジック用で、ファクトリはプライベートメソッドを使ったもっと複雑なロジック用のファクトリであると思われるので、以下のフィドルコードを更新したようです。プライベート機能をサポートすることができますか?

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

説明

あなたはここで違うものを手に入れました:

最初:

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

ref:angular.serviceとangular.factory

秒:

AngularJSのすべてのプロバイダ(値、定数、サービス、工場)はシングルトンです。

3番目:

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

どうして ?

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

refhttp://www.Amazon.com/Mastering-Web-Application-Development-AngularJS/dp/1782161821 ).


使用法

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

Factory:インスタンスを作成するために新たに追加されることができる「クラス」関数を返すのに役立ちます。

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

他の場合では もしあなたがサービスのインスタンスを返したいならば単にservice を使ってください。

しかし、時間の経過とともに80%のケースでファクトリを使用することになるでしょう。

詳細については、 http://blog.manishchhabra.com/2013/09/angularjs-service-vs-factory-with-example/


更新:

ここに優秀な投稿: http://iffycan.blogspot.com.ar/2013/05/angular-service-or-factory.html

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


更新:

AngularJSチームは自分の仕事をして説明をします: http://docs.angularjs.org/guide/providers

そしてこのページから:

「ファクトリとサービスは最も一般的に使用されるレシピです。それらの唯一の違いは、サービスレシピはカスタムタイプのオブジェクトに対してうまく機能するのに対し、ファクトリはJavaScriptプリミティブと関数を生成できるということです。」

277
Thomas Pons

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をすることができます、その車に特有の多数のシリンダーを渡すこと。 CarServiceは関数ではなくオブジェクトなので、new CarServiceを実行することはできません。

工場はこのようには機能しません。

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

そして、インスタンス化するための関数を自動的に返します。それができないからです(プロトタイプなどに追加する)。

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. Hashなどの単純なオブジェクトが必要な場合は、Serviceを使用します。{foo; 1、bar:2}コーディングは簡単ですが、インスタンス化することはできません。

  2. New Customer()、new Comment()など、オブジェクトをインスタンス化する必要があるときはFactoryを使います。

  3. 設定が必要な場合はプロバイダを使用してください。すなわち、テストURL、QA URL、製造URL。

あなたがファクトリでオブジェクトを返しているだけであるとわかったなら、おそらくserviceを使うべきです。

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

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

代わりにserviceを使ってください。

app.service('CarService', function() {
    this.numCylinder = 4;
});
109
Jonathan.

これらすべてのプロバイダの概念は、最初に登場したものよりもはるかに単純です。あなたがプロバイダあなたを詳細に分析して、異なる部分を引き出すなら、それは非常に明確になります。

簡単に言えば、これらのプロバイダのそれぞれが、provider> factory> value/constant/serviceの順に、もう一方のプロバイダを特殊化したものです。

プロバイダができる限り長くあなたができる限りプロバイダを使用することができます。その結果、より少ないコードを書くことになります。それがあなたが望んでいることを達成しないなら、あなたはチェーンを上がることができます、そしてあなたはただもっと多くのコードを書く必要があるでしょう。

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

AngularJSプロバイダ、ファクトリ、サービスなどはすべて同じものです。http://www.simplygoodcode.com/wp-content/uploads/2015/11/angularjs-provider-service-factory- highlight.png

私が行ってから画像を得たブログ記事からのより多くの詳細と例については: http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider -and-factory-in-angularjs /

19
Luis Perez

ファクトリとサービスの両方が、プロバイダによって設定され、コントローラと実行ブロックに注入されることができるシングルトンオブジェクトをもたらします。注入先の観点からは、オブジェクトが工場から来たのかサービスから来たのかには全く違いはありません。

それでは、いつ工場を利用し、いつサービスを利用するのでしょうか。それはあなたのコーディングの好みに煮詰まり、そして他には何もない。あなたがモジュラーJSパターンを好めばそれから工場に行きなさい。あなたがコンストラクタ関数( "クラス")スタイルを好めばそれからサービスのために行きなさい。どちらのスタイルもプライベートメンバーをサポートしています。

このサービスの利点は、OOPの観点から直観的にわかりやすいことです。「クラス」を作成し、プロバイダと連携して、モジュール間で同じコードを再利用してインスタンス化されたオブジェクトは、コンフィグブロック内のコンストラクタに異なるパラメータを渡すことによって単純になります。

8
Steve Lang

たとえ彼らがすべてのサービスや工場がシングルトンであると言ったとしても、私はそれに100パーセント賛成しません。私は工場はシングルトンではないと言うでしょう、そしてこれが私の答えのポイントです。私は本当にすべてのコンポーネントを定義する名前(Service/Factory)について考えます。

Aファクトリはシングルトンではないので、注入するときに必要なだけ作成できます。つまり、オブジェクトのファクトリのように機能します。あなたはあなたのドメインのエンティティのファクトリを作成し、あなたのモデルのオブジェクトのようになることができるこのオブジェクトでより快適に作業することができます。複数のオブジェクトを取得すると、それらをこのオブジェクトにマップでき、DDBBとAngularJsモデルの間の別のレイヤーのように機能できます。オブジェクトにメソッドを追加して、AngularJsアプリケーションをもう少しオブジェクトに向けることができます。

一方、サービスはシングルトンなので、作成できるのは1種類だけで、作成できないかもしれませんが、コントローラにインジェクトするときに1つのインスタンスしかありません。そのため、サービスはコントローラに対してより一般的なサービス(呼び出しの休止、機能など)を提供します。

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

ファクトリーがサービスと比較してできない、またはそれ以上に優れているものは何もありません。そしてその逆です。工場はもっと人気があるようです。その理由は、プライベート/パブリックメンバーを処理するのに便利だからです。この点でサービスはもっと不器用でしょう。サービスをコーディングするときは、「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定数を使用すると、このことによってコードの読みやすさが低下します。さらに、サービスのプロトタイプでは非公開のメンバーは表示されません。公開されているメンバーだけが利用できます。

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を使用する方が便利です。工場にはこれらの欠点はありません。デフォルトで使用することをお勧めします。

2
Andrew Krook

サービス

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

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

工場

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

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

使用法:インスタンスを作成するために新しく追加できる 'class'関数を返すのに便利です。

プロバイダ

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

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

使用法:インスタンスを作成するために新しく追加することができますが、注入される前に何らかの設定が必要な 'class'関数を返すのに便利です。 。プロジェクト間で再利用可能なクラスにはおそらく便利でしょうか。これでもやや濁っています。

0

FactoryとServiceが最も一般的に使用されている方法です。唯一の違いは、Serviceメソッドは継承階層を必要とするオブジェクトに適しているのに対し、FactoryはJavaScriptのプリミティブと関数を生成できるという点です。

Provider関数はコアメソッドであり、他のすべてのものは単なる構文糖です。グローバル構成を必要とする再利用可能なコードを構築している場合にのみ必要です。

サービスを作成するには、Value、Factory、Service、Provider、Constantの5つの方法があります。あなたはここでこれについてより多くを学ぶことができます 角度サービス 、この記事は実用的なデモ例でこれらすべての方法を説明します。

0
user3114005

両方ともあなたが望む方法を使うことができます:create objectまたはj両方から関数にアクセスしたい


サービスから新しいオブジェクトを作成することができます

app.service('carservice', function() {
    this.model = function(){
        this.name = Math.random(22222);
        this.price = 1000;
        this.colour = 'green';
        this.manufacturer = 'bmw';
    }
});

.controller('carcontroller', function ($scope,carservice) { 
    $scope = new carservice.model();
})

注意 :

  • デフォルトでserviceはコンストラクタ関数ではなくオブジェクトを返します。
  • だから、コンストラクタ関数がthis.modelプロパティに設定されているのはそのためです。
  • このサービスのためにオブジェクトを返しますが、そのオブジェクトの中に新しいオブジェクトを作成するために使用されるコンストラクタ関数があります。

ファクトリから新しいオブジェクトを作成することができます

app.factory('carfactory', function() {
    var model = function(){
        this.name = Math.random(22222);
        this.price = 1000;
        this.colour = 'green';
        this.manufacturer = 'bmw';
    }
    return model;
});

.controller('carcontroller', function ($scope,carfactory) { 
    $scope = new carfactory();
})

注意 :

  • デフォルトではfactoryはobjectではなくコンストラクタ関数を返します。
  • そのため、コンストラクタ関数を使って新しいオブジェクトを作成することができます。

単純な関数にアクセスするためのサービスを作成する

app.service('carservice', function () {
   this.createCar = function () {
       console.log('createCar');
   };
   this.deleteCar = function () {
       console.log('deleteCar');
   };
});

.controller('MyService', function ($scope,carservice) { 
    carservice.createCar()
})

単純な関数にアクセスするためのファクトリを作成する

app.factory('carfactory', function () {
    var obj = {} 
        obj.createCar = function () {
            console.log('createCar');
        };
       obj.deleteCar = function () {
       console.log('deleteCar');
    };
});

.controller('MyService', function ($scope,carfactory) { 
    carfactory.createCar()
})

結論:

  • 新しいオブジェクトを作成するか単純な関数にアクセスするかにかかわらず、両方とも使用することができます
  • 一方を他方を使用して、パフォーマンスへの影響はありません。
  • どちらもシングルトンオブジェクトであり、アプリごとに作成されるインスタンスは1つだけです。
  • 参照が渡されるすべての場所で1つのインスタンスになります。
  • 角度付き文書では、ファクトリはserviceと呼ばれ、またserviceはserviceと呼ばれます。
0
vijay