2013-12-16 29 views
13

私はAngularでとても緑色ですが、私はこれを正しく検索することさえ確信していません。ディレクティブとサービスの用語全体が私にはまだ混乱していますが、それは私の質問ではありません。AngularJS - サービスからコントローラ関数を呼び出す

私がバックアップするために、この優れた記事シリーズのフロントを読んだ:私は自分のアプリケーションでは、この時点で午前なぜhttp://www.ng-newsletter.com/posts/beginner2expert-how_to_start.html

です。なぜ私の質問がサービスとコントローラの関係にもっと関係しているのか分かりません。構文に関わらず。

これはアプリの概要です:

私は1つのコントローラを持っています。これはオフになり、PHPファイルへのAJAX呼び出しを使用してユーザーのためのファームデータの束を取得し、それ自身の$ scopeを使用して画面に表示します。

var masterApp = angular.module('masterApp', ['myFilters','commonControls']); 

masterApp.controller('MasterCtrl', ['$scope','$http', '$filter', 'commonFarmSelector', 
    function($scope, $http, $filter, commonFarmSelector){ 

     ... 

     $scope.masterCtrl.loadFarmData = function(farmId) { 
      var postdata = { 
       "farmId":farmId 
      }; 

      $http.post('/service/farmproduction', postdata).success(function (data) { 
       // Do stuff with the $scope using data 
      } 
     } 

     $scope.masterCtrl.loadFarms(); 
} 

「commonControls」と呼ばれるものが注入されています。これは複数のコントローラで再利用されるコントロールを保持するために作成したモジュールです。この場合は、農場のリストが含まれているドロップダウンフィールドは、ユーザは、(また、AJAX呼び出しによって得られた)にアクセスする場合があります:

var commonControlsApp = angular.module('commonControls', []); 

commonControlsApp.controller('farmSelectorCtrl', ['$scope', '$http',function($scope, $http) { 

    $scope.farmSelectorCtrl ={} 

    // Change entire farm view when a different farm is selected 
    $scope.farmSelectorCtrl.switchUserFarm = function() { 
     var farmId = $scope.farmSelectorCtrl.selectedUserFarm; 
     $scope.masterCtrl.loadFarms(farmId); // !!! Direct link to masterCtrl 
    }; 

    // Get a list of the user's farms 
    $http.post('/service/userfarms').success(function (data) { 
     $scope.farmSelectorCtrl.userFarms = data.getFarmsPerUserResult.farmIds; 
    }); 

}]); 

これが正常に動作します。しかし、わかるように、farmSelectorはmasterCtrlに直接リンクされています。そのloadFarmData関数の動作は、そのコントローラに固有です。言い換えれば、それはそのページに適用されるものだけを実行します。

問題は、このfarmSelectorは他のページで使用されることです。変更イベントの正確な動作はページごとに異なります。だから、私はこの行動がどこに座るべきかを考え出すのに苦労しています。また、farmSelectorを使用してコントローラーに依存して呼び出される方法。

上記のリンク先の記事は、このfarmSelectorがサービス内に存在し、他の場所で再利用できるようにすることを示しています。しかし、私は、ジェネリックサービスにイベントがトリガーされたときに取る特定のアクションを与える方法について、まだ混乱しています。

答えて

11

この記事でも同様の理由でサービスを受けることを強くお勧めします。また、あなたの問題に対する大きな答えがあります。

あなたが望む技術用語はのコールバック機能です。これは、正確には、イベントが発生したときに取る特定のアクションであり、記事の「サービス」セクションでは、これを行う方法の良い例が示されています。

だから私たちは一つの方法を持っているgithubServiceと呼ばれる今のサービスを、持っている

angular.module('myApp.services', []) 
    .factory('githubService', ['$http', function($http) { 

    var doRequest = function(username) { 
     return $http({ 
     url: 'https://MySuperURL.com/getTheData' 
     }); 
    } 

    return { 
     events: doRequest 
    }; 

}]); 

を(私は重要な部分にまでトリミングされてきた)サービスの記事のこのセクションを見てみましょう: (本当にdoRequestのためだけに別の名前である。それは記事のコードにマッチするように、私は名前の変更を保管)events舞台裏ここに隠し

はと呼ばれることがある$q APIであり、 「約束」API。関数$httpは、「約束」オブジェクトを返します。これは、「約束」が行われたときに何が起こるべきかをコードが把握するための単なる方法です。たとえば、この次のコードを見てみましょう(また、記事のバージョンから変更しました)。

app.controller('ServiceController', ['$scope', 'githubService', 
function($scope, githubService) { 

    // uses the $http service to call the GitHub API 
    // and returns the resulting promise 
    githubService.events(newUsername) 
    .success(function(data, status, headers) { 
     // do magic stuff with the result 
     // (which is in the data param) 
     $scope.events = data.data; 
    }) 
}); 

]]);

「マジック」が起こっている場所です。 success()への呼び出しを見ると、実際には要求が働くときに実行されるfunctionを渡していることがわかります。関数はまだクロージャーのためにServiceControllerのすべての変数にアクセスできるため、$scopeと他の変数を使用することはできます。しかし、毎回異なる関数を渡すことによって、コントローラごとに異なるsuccess()メソッドを書くことは非常に可能です。これにより、複数のコントローラが異なるアクションをとることができます。要求が終了すると、与えられたすべての関数が呼び出されます(success)。

このコード例に従うと実用的なモデルを得ることができますが、$q in angularをご覧になり、callback functionsについてもこの記事をご覧ください。あなたは何が起こっているのか本当に理解する必要がありますが、良いニュースは両方とも角度が非常に頻繁に使用されているので、あなたの時間の価値があるでしょう。

+0

私は頭の数時間前にこの答えを見て、それをどうやって行うのがいいかと思います。努力してくれてありがとう –

関連する問題