2013-04-17 15 views
17

私はAngularJS初心者です。factory,servicecontrollerの概念と相違点を理解し始めました。私が理解するように、factoryは、注入可能な「値オブジェクト」を返すために使用されます。私はこのような何かを見てきましたほとんどの例:私のcontroller注入可能なクラス(コンストラクタ)を作成する

angular.module('module.factories', function() { 
    factory('FactoryObject', function() { 
     return { 
      someFunction: function(someParam) {}; 
      someOtherFunction: function(someOtherParam) {}); 
     }; 
    }); 
}); 

は、私はこのオブジェクトを使用することができるようにしたいが、それを再することができますので、私は、コントローラにそれをインスタンス化/初期化したいですコントローラー内のイベント/アクションに応じて初期化されます。したがって、私は代わりに工場でコンストラクタ関数を返すことができるかどうか疑問に思っていましたか?

angular.module('module.factories', function() { 
    factory('FactoryObject', function() { 

     function FactoryObject(initParam) { 
     } 

     FactoryObject.prototype.someFunction = function() {}; 

     return FactoryObject; 

    }); 
}); 

これは、角張った工場に適したパターンですか?それとも、このようなカスタムオブジェクトのためにファクトリを使用するのはちょうど "過度な"ことでしょうか?私はそれをライブラリのjsファイルに含めるだけで、そこから参照する必要がありますか?工場に置くことの1つの利点は、使用されている場所に注入されるので、テストで模擬するのは簡単だということです。 Angularには、代わりに使用できる他のメカニズムがありますか?

+0

私はカスタムファクトリオブジェクトを提供関数内で宣言するのは、アプリケーションの残りの部分から抽象化されているということです。 – Bart

+0

実際にコンストラクタ関数が必要な場合は、何をやっているのですか? – ganaraj

+0

@ganaraj私が必要とする理由は、コントローラの寿命中にコントローラ内で複数回再初期化される可能性があるからです。私は普通のオブジェクトを返すだけで、その上に 'init'メソッドを持たせることができますが、それがどうなるかは分かりません。フィードバックをお寄せいただきありがとうございます。 – NilsH

答えて

3

あなたは正しかった、これは注入可能な "クラス"(コンストラクタ)を作成する方法です。あなたのクラスで使用される他のものを注入する必要がある場合ただし、factoryを使用することが必要なだけである:

.factory('Class', ['$q', function ($q) { 
    function Class() {} 
    Class.prototype = { 
     constructor: Class, 
     doSomeAsyncAction: function() { 
      return $q(function (resolve, reject) { 
       // ... 
      }); 
     }, 
     // ... 
    }; 
    return Class; 
}) 

あなたは完全に独立したクラス(例えば、いくつかのデータ構造)を作成している場合は、あなただけconstantを使用することができ、ので、あなたのクラスでもサービスプロバイダで利用可能であること:追記として

(function (undefined) { 
    function Class() {} 
    Class.prototype = { ... }; 
    angular.module(...) 
     .constant('Class', Class); 
})(); 

providerを使用すると、この中にあなたを助けるために行くのではありません。プロバイダは完全に異なる目的を果たし、(他のものの中でも)ファクトリ関数を返します。ファクトリ関数は、最初に要求されたインジェクションで使用され、サービスの単一のインスタンスを作成します。プロバイダを使用して、アプリケーション構成の_configフェーズでその単一サービスインスタンスを構成できるようにします(see documentation)。

(function (myModule) { 
    'use strict'; 

    myModule.service('myService', [ 
     function() { 
      var serivce = this; 
      var obj = null; 

      service.func1 = function(a, b) { 

      } 

      service.func2 = function(c, d) { 
       . . . 
       return something; 
      } 

      var constructor = function(myObj) { 
       obj = myObj; 

       return service; 
      } 

      return constructor; 
     } 
    ]); 
}(angular.module("myModule"))) 

(function(myModule) { 
    'use strict'; 

    myModule.controller('myController', [ 
     '$scope', 'myService', function($scope, myService) { 

      var service = myService($scope.someObj); 

      $scope.someOtherObj = service.func2($scope.a, $scope.b); 

     } 
    ]); 
}(angular.module("myModule"))) 

サービスから返された唯一のものは、コンストラクタで、その後のサービスは、サービスの残りを返します。

+0

私たちは名誉ある戦いをしました...今私は自分の剣に落ちます。 –

8

私は同じ問題を抱えています。ここに私が実装何:今

angular.module('foo', []) 
.factory('Foo', ['$http', function($http) { 
    return function(a, b) { 
    this.arr = []; 
    this.a = a; 
    this.b = b; 
    this.random = Math.floor(Math.random()*11); 

    this.someFunc = function(c) { 
     this.arr.push(c); 
    }; 
    }; 
}]); 

、私が行うことができます。

var f1 = new Foo('A', 'B'); 
f1.random; // i.e. 0 
f1.someFunc('z'); // only affects f1.arr 
var f2 = new Foo('C', 'D'); 
f2.random; // i.e. 8 
f2.someFunc('y'); // only affects f2.arr 

は、物事をよりモジュール化します。希望が役立ちます。

1

私は同じ質問をしました。オブジェクト指向のAngularJSサービスをセットアップする方法に関するすばらしい記事を見つけました。 Here's the article。サービスではなく工場の使用に関する注意に注意してください。また、オブジェクトの拡張についても説明します。私はセットアップが非常に簡単で、Javascriptをシンプルかつ簡単に保ちながらAngularと完全にフィットすることが分かりました。

シングルトンであり、インスタンス化する必要のないファクトリサービスでは、パフォーマンス上の利点を持つオブジェクトリテラルアプローチを使用します。

1

は、ここで私は問題を解決する方法です。

関連する問題