2016-09-19 17 views
2

私は、ブロードキャストイベントを聞く必要がある工場を持っています。私は$scopeを工場に注入したので、$scope.$onを使うことができました。しかし、すぐに私が$scopeをパラメータリストに追加すると、インジェクタエラーが発生します。

これは正常に動作します:

angular.module('MyWebApp.services') 
    .factory('ValidationMatrixFactory', ['$rootScope', function($rootScope) { 
     var ValidationMatrixFactory = {}; 
     return ValidationMatrixFactory; 
    }]); 

これは、インジェクタのエラーがスローされます。

angular.module('MyWebApp.services') 
    .factory('ValidationMatrixFactory', ['$scope', '$rootScope', function($scope, $rootScope) { 
     var ValidationMatrixFactory = {}; 
     return ValidationMatrixFactory; 
    }]); 

は、なぜ私は、工場出荷時に$scopeを注入することはできませんか?もし私ができなければ、$rootScope以外のイベントを聞く方法はありますか?

+2

'$ scope'はコントローラとビューのみです。ファクトリがビューに接続されていません。だからあなたはそれを注射することができません。工場の '$ rootScope'のイベントを聞いても何も問題ありません。 –

答えて

5

コントローラを接続するために$ scopeが使用されるため、工場は実際には$ scopeを使用するものではありません。

これまでrootScopeにどのようにブロードキャストできますか。

$rootScope.$on() 
+0

私は '$ rootScope。$ on()'を使ってリスナーが範囲外に出ることはないので、イベントが複数回発生するということは悪いことを読んでいます。それはここには当てはまりませんか? – Legion

+0

はい、彼のことが起こります.JoelCDoyleはおそらくそれが大丈夫だと言っていますし、工場にとっては必要です。私は詳細についてはこの投稿を参照します。 –

+0

'$ rootScope。$ on'はコントローラーのコンテキストでは悪いことがありますが、"外出する "$ scope"がない工場ではできません –

0

サービスで$ scopeを使用することはできませんが、サービスは「ストア」として使用できます。私はReactJS上でアプリケーションを開発しながら、AltJS/Reduxに触発された以下のアプローチを使用します。

私は、ビューがバインドされているスコープを持つコントローラを持っています。そのコントローラーにはthis.state = {}のサービスからその値を取得する変数$scope.stateがあります。このサービスは、「状態」に触れるために「許可」された唯一のコンポーネント(あなた、開発者、これは私たち自身に従うべきルール)です。

例は

(function() { 
 
    'use strict'; 
 
    angular.module('app', ['app.accounts']); 
 
    
 
    // my module... 
 
    // it can be defined in a separate file like `app.accounts.module.js` 
 
    angular.module('app.accounts', []); 
 
    
 
    angular.module('app.accounts') 
 
     .service('AccountsSrv', [function() { 
 
      var self = this; 
 

 
      self.state = { 
 
       user: false 
 
      }; 
 
      
 
      self.getAccountInfo = function(){ 
 
       var userData = {name: 'John'}; // here you can get the user data from an endpoint 
 
       self.state.user = userData;  // update the state once you got the data 
 
      }; 
 
     }]); 
 
    
 
    // my controller, bound to the state of the service 
 
    // it can be defined in a separate file like `app.accounts.controller.js` 
 
    angular.module('app.accounts') 
 
     .controller('AccountsCtrl', ['$scope', 'AccountsSrv', function ($scope, AccountsSrv) { 
 
      $scope.state = AccountsSrv.state; 
 
      
 
      $scope.getAccountInfo = function(){ 
 
       // ... do some logic here 
 
       // ... and then call the service which will 
 
       AccountsSrv.getAccountInfo(); 
 
      } 
 
     }]); 
 
})();
<script src="https://code.angularjs.org/1.3.15/angular.min.js"></script> 
 
<div ng-app="app"> 
 
    <div ng-controller="AccountsCtrl"> 
 
    Username: {{state.user.name ? state.user.name : 'user info not available yet. Click below...'}}<br/><br/> 
 
    <a href="javascript:void(0);" ng-click="getAccountInfo()">Get account info</a> 
 
    </div> 
 
</div>

この点をもう少し明確にすることができ、このアプローチの利点は、あなたが複数の場所に$watchまたは$onを設定したり、うんざりするほど呼び出す必要はありませんですコントローラーの状態を更新する必要があるたびに$scope.$apply(function(){ /* update state here */ })コンポーネントとサービスの関係は1つのコントローラが1つまたは複数のサービスと話すことができるため、複数のコントローラがサービスに対話することもできます。このアプローチは、真実の単一の情報源を維持することに焦点を当てています。

私は大規模なアプリケーションでこのアプローチを使用しました...それは魅力的なように機能しています。

状態を保持する場所と更新方法について少し明確にすることができれば幸いです。

関連する問題