2017-02-14 21 views
0

2つの独立したコントローラ(2つの別々のJSファイル)に2つのコードがあります。一方はAngular $scope.$broadcastイベントをトリガーし、もう一方は$scope.$onリスナーをトリガーします。

第1のコントローラ(ファイル)スニペット:

var Controller1 = function($scope) { 
    $scope.triggerMyEvent = function(){ 
     $scope.$broadcast('triggeredEvent'); 
    } 
    $scope.go = function (path) { 
     $location.path(path); 
    }; 
} 

前記第二のコントローラ(ファイル)スニペット:

var Controller2 = function($scope) { 
    $scope.$on('triggeredEvent',function(event){ 
     console.log('found triggered event'); 
    }); 
} 

を次のようにアプリケーションが一緒に配線されている:

var app = angular.module("myApp", ["ngRoute"]); 
app.config(function($routeProvider) { 
    $routeProvider 
    .when("/page2", { 
     controller : Controller2 
     template : "/page2.html" 
    }) 
    .otherwise({ 
     template : "<p>Error</p>" 
    }); 
}); 

第1コントローラindex.htmlファイルのng-controllerディレクティブによって参照されます。そして上記の他のファイル、page2.htmlは、参照とインデックスのアクションからロードされます。

のindex.html:

<body ng-controller="Controller1"> 
    <button ng-click="go('/page2.html')">Page 2</button> 
</body> 

私は$scope.$broadcastイベントがトリガされ、このコードをロード初めてと$scope.$onリスナーはそれをうまくキャッチします。 $scope.$onリスナーはそれをキャッチしませんが、私はそれをリロードする場合。明確にするために、初期ロード時にイベントがトリガーされ、正常に捕捉されます。だから私のサーバーを再起動し、ページにアクセスします。しかし、私がページ(F5)をリフレッシュすると、そのイベントは解雇されているものの、捕まえられていないと考えられます。私はこれに取り組んでいないので、私は$ scope/$ rootScopeや$ broadcast/$ emit/$ onなどの情報を読んだことがあるが、知識が不足していると推測している。どんな助けもありがとうございます。私は関連する問題に関するいくつかの記事を見る。差し迫った関連性は見られない。

Angular $broadcast only updating after page refresh

AngularJS event-based communication through isolate scope

私はスコープを隔離するために、関連すると考えているが、私はまだ動作するように何かを得ることができていない最も有望参照:私はこの記事を注意しなかったが。

+0

私たちはあなたのコードの残りの部分を参照する必要があります。これはあなたの質問に答えるだけの情報ではありません。 'triggerMyEvent'はどのように呼び出されますか?関連するテンプレートはありますか?コントローラの定義を見てみましょう –

+0

こんにちは、私はより関連性の高いコードを追加してみます。しかし、私は単純に関数を呼び出し、コンソールロギング(上記には示されていません)を使用して、毎回トリガーされることを確認します。 – Gedalya

+0

より完全な画像を提供するようにコードを更新しました。 – Gedalya

答えて

1

$broadcastおよび$onは、スコープ階層を介して機能します。 $broadcastは、その子孫に向かってスコープ階層の下にメッセージを送信します。 $onリスナーは、メッセージがブロードキャストされたスコープの子孫でなければなりません。 $rootScopeからブロードキャストすると、すべてのスコープが子孫になり、すべてのスコープがメッセージを聞くことができます。だから、あなたのメッセージはすべてのスコープによって到達可能であることを保証するための1つの方法はそうのようにそれを放送するためにされています。理想的には、メッセージとリタールートスコープを望んでいない

// just to demostrate. don't put this in a controller 
$scope.triggerMyEvent = function(){ 
    $rootScope.$broadcast('triggeredEvent'); //don't do this in a controller 
} 

。コントローラーが初期化されるたびに新しいリスナーを追加して保持するので、コントローラで$rootScope.$onを使用するとさらに悪化します。あなたの問題の根底に到達するには、この階層に注意を払う必要があります。これがリスナーに影響します。この階層の

一例:

<div ng-controller="ParentCtrl"> 
    <div ng-controller="ChildCtrl"> 
    </div> 
</div> 

<div ng-controller="SiblingCtrl"> 
</div> 

function ParentCtrl($scope) { 
    $scope.$broadcast('parentMsg'); 
} 

function ChildCtrl($scope) { 
    $scope.$on('parentMsg', function() { 
    // will receive message 
    }); 
} 

function SiblingCtrl($scope) { 
    $scope.$on('parentMsg', function() { 
    // will not receive message 
    }); 
} 
+1

しかし、$ scope. $は新しい$ rootScopeとして1回以上トリガされるかもしれません。$ブロードキャストはその関数が呼び出されるたびに作成されます。 理想的には、$ scope。$ broadcastを持つコントローラを親クラスにする必要があります。 – Chait

+0

サービスでは、たとえば、ローカルスコープはありません。メッセージをブロードキャストする場合は、 '$ rootScope'を使う必要があります。しかし、それは実際にコントローラ内で使用されるべきではありません –

+0

私は完全に同意します。あなたが提案したように、関数はどこから呼び出されているかのような詳細情報が必要です – Chait

関連する問題