scope
変数を使用して、最初のコントローラーで2番目のコントローラーのメソッドを呼び出そうとしています。これは私の最初のコントローラーのメソッドです:
$scope.initRestId = function(){
var catapp = document.getElementById('SecondApp');
var catscope = angular.element(catapp).scope();
catscope.rest_id = $scope.user.username;
catscope.getMainCategories();
};
rest_id
の値を設定できますが、何らかの理由でgetMainCategories
を呼び出すことはできません。コンソールには次のエラーが表示されます。
TypeError:オブジェクト#にはメソッド 'getMainCategories'がありません
上記のメソッドを呼び出す方法はありますか?
編集:
次のアプローチを使用して、2つのアプリを同時に読み込みました。
angular.bootstrap(document.getElementById('firstAppID'), ['firstApp']);
angular.bootstrap(document.getElementById('secondAppID'), ['secondApp']);
ここでは間違いなくサービスを使用できますが、同じことを行う他のオプションがあるかどうかを知りたかったです!
2つのコントローラー間で通信するための最善の方法は、イベントを使用することです。
このチェックアウトでは、$on
、$broadcast
、および$emit
を確認します。
一般的な使用例では、angular.element(catapp).scope()
の使用法は、jqueryイベント内など、angularコントローラーの外部で使用するために設計されました。
理想的には、コントローラー1で次のようにイベントを作成します。
$scope.$on("myEvent", function (event, args) {
$scope.rest_id = args.username;
$scope.getMainCategories();
});
そして、2番目のコントローラーでは、
$scope.initRestId = function(){
$scope.$broadcast("myEvent", {username: $scope.user.username });
};
編集:2つのモジュール間の通信であることがわかりました
firstApp
モジュールを、angular.module
を宣言するsecondApp
への依存関係として含めてみてください。そうすれば、他のアプリと通信できます。
ここに良いデモがあります Fiddle $scope.$on
を介してディレクティブおよび他のコントローラーで共有サービスを使用する方法
HTML
<div ng-controller="ControllerZero">
<input ng-model="message" >
<button ng-click="handleClick(message);">BROADCAST</button>
</div>
<div ng-controller="ControllerOne">
<input ng-model="message" >
</div>
<div ng-controller="ControllerTwo">
<input ng-model="message" >
</div>
<my-component ng-model="message"></my-component>
JS
var myModule = angular.module('myModule', []);
myModule.factory('mySharedService', function($rootScope) {
var sharedService = {};
sharedService.message = '';
sharedService.prepForBroadcast = function(msg) {
this.message = msg;
this.broadcastItem();
};
sharedService.broadcastItem = function() {
$rootScope.$broadcast('handleBroadcast');
};
return sharedService;
});
同様に、共有サービスをディレクティブで使用できます。コントローラーセクションをディレクティブに実装し、$scope.$on
を使用できます
myModule.directive('myComponent', function(mySharedService) {
return {
restrict: 'E',
controller: function($scope, $attrs, mySharedService) {
$scope.$on('handleBroadcast', function() {
$scope.message = 'Directive: ' + mySharedService.message;
});
},
replace: true,
template: '<input>'
};
});
そして、ControllerZero
がprepForBroadcast
を呼び出すトリガーとして使用される3つのコントローラー
function ControllerZero($scope, sharedService) {
$scope.handleClick = function(msg) {
sharedService.prepForBroadcast(msg);
};
$scope.$on('handleBroadcast', function() {
$scope.message = sharedService.message;
});
}
function ControllerOne($scope, sharedService) {
$scope.$on('handleBroadcast', function() {
$scope.message = 'ONE: ' + sharedService.message;
});
}
function ControllerTwo($scope, sharedService) {
$scope.$on('handleBroadcast', function() {
$scope.message = 'TWO: ' + sharedService.message;
});
}
ControllerOne
およびControllerTwo
listen message
は、$scope.$on
ハンドラーを使用して変更されます。
各コントローラーには独自のスコープがあるため、問題が発生しています。
同じデータへのアクセスを必要とする2つのコントローラーを持つことは、サービスが必要な典型的な兆候です。 angularチームは、ビューとサービスをつなぐだけのシンコントローラーを推奨しています。そして具体的には、「サービスはコントローラー間で共有状態を保持する必要があります」。
幸いなことに、これを正確に説明するニースの15分のビデオがあります(サービスを介したコントローラー通信): video
Angularの原作者の一人であるMisko Heveryは、この推奨事項(この状況でサービスを使用すること)について Angular Best Practices (このトピックについては28:08までスキップしてください。トーク全体を視聴することをお勧めします)。
イベントを使用できますが、それらは分離したい2つのパーティ間の通信用にのみ設計されています。上記のビデオでは、Miskoがアプリをより脆弱にする方法を説明しています。 「ほとんどの場合、サービスを注入して直接通信を行うことが好まれ、より堅牢です」。 (53:37から始まる上記のリンクをチェックして、彼がこれについて話しているのを聞いてください)