899

andメソッド$scopeを使用して、あるコントローラーから別のコントローラーにオブジェクトを送信するにはどうすればよいですか?.$emit.$on

function firstCtrl($scope) {
    $scope.$emit('someEvent', [1,2,3]);
}

function secondCtrl($scope) {
    $scope.$on('someEvent', function(mass) { console.log(mass); });
}

それは私が思うようには機能しません。どのよう$emit$on働きますか?

4

12 に答える 12

1506

まず、親子スコープの関係が重要です。イベントを発行するには、次の 2 つの可能性があります。

  • $broadcast-- イベントをすべての子スコープに下向きにディスパッチします。
  • $emit-- スコープ階層を介して上方にイベントをディスパッチします。

コントローラー (スコープ) の関係については何も知りませんが、いくつかのオプションがあります。

  1. スコープのスコープがスコープのfirstCtrl親である場合、コードはin にsecondCtrl置き換えることで機能するはず$emitです。$broadcastfirstCtrl

    function firstCtrl($scope)
    {
        $scope.$broadcast('someEvent', [1,2,3]);
    }
    
    function secondCtrl($scope)
    {
        $scope.$on('someEvent', function(event, mass) { console.log(mass); });
    }
    
  2. スコープ間に親子関係がない場合は$rootScope、コントローラーに注入して、すべての子スコープにイベントをブロードキャストできます (つまり、 もsecondCtrl)。

    function firstCtrl($rootScope)
    {
        $rootScope.$broadcast('someEvent', [1,2,3]);
    }
    
  3. 最後に、イベントを子コントローラから上位のスコープにディスパッチする必要がある場合は、 を使用できます$scope.$emit。スコープがスコープのfirstCtrl親である場合secondCtrl:

    function firstCtrl($scope)
    {
        $scope.$on('someEvent', function(event, data) { console.log(data); });
    }
    
    function secondCtrl($scope)
    {
        $scope.$emit('someEvent', [1,2,3]);
    }
    
于 2013-01-24T13:41:29.233 に答える
146

さらに、@zbynour によって提案されたオプションのより良い代替手段として、4 番目のオプションを提案します。

送信コントローラと受信コントローラの関係に関係なく$rootScope.$emit使用します。$rootScope.$broadcastそうすれば、イベントは のセット内に留まりますが、イベントは$rootScope.$$listenersすべて$rootScope.$broadcastの子スコープに伝播しますが、そのほとんどはおそらくそのイベントのリスナーにはなりません。そしてもちろん、受信コントローラーの最後では、 を使用するだけ$rootScope.$onです。

このオプションでは、コントローラーの rootScope リスナーを破棄することを忘れないでください。

var unbindEventHandler = $rootScope.$on('myEvent', myHandler);
$scope.$on('$destroy', function () {
  unbindEventHandler();
});
于 2014-04-06T19:34:26.700 に答える
39

$scope objectあるコントローラーから別のコントローラーに送信するには、最もよく使用される$rootScope.$broadcast$rootScope.$emitここで説明します。

ケース 1 :

$rootScope.$broadcast:-

$rootScope.$broadcast('myEvent',$scope.data);//Here `myEvent` is event name

$rootScope.$on('myEvent', function(event, data) {} //listener on `myEvent` event

$rootScopeリスナーは自動的に破棄されません。を使用して破壊する必要があります$destroy$scope.$onリスナー$scopeは自動的に破棄されるため、つまり $scope が破棄されるとすぐに使用することをお勧めします。

$scope.$on('myEvent', function(event, data) {}

または、

  var customeEventListener = $rootScope.$on('myEvent', function(event, data) {

  }
  $scope.$on('$destroy', function() {
        customeEventListener();
  });

ケース 2:

$rootScope.$emit:

   $rootScope.$emit('myEvent',$scope.data);

   $rootScope.$on('myEvent', function(event, data) {}//$scope.$on not works

$emit と $broadcast の主な違いは、$rootScope.$on を使用して $rootScope.$emit イベントをリッスンする必要があることです。これは、発行されたイベントがスコープ ツリーを通過することがないためです。.
この場合も、$broadcast の場合と同様にリスナーを破棄する必要があります。

編集:

$rootScope.$broadcast + $scope.$on私は使うのではなく使うのが 好き$rootScope.$emit+ $rootScope.$onです。コンボは、$rootScope.$broadcast + $scope.$on深刻なパフォーマンスの問題を引き起こす可能性があります。これは、イベントがすべてのスコープでバブル ダウンするためです。

編集2

この回答で対処されている問題は、angular.js バージョン 1.2.7 で解決されています。$broadcast は、未登録のスコープでのバブリングを回避し、$emit と同じ速度で実行されるようになりました。

于 2016-04-02T18:54:47.637 に答える
10

$rootScope を使用して、同じアプリ内のコントローラー間でイベントを送信およびキャプチャする必要があります。$rootScope 依存関係をコントローラーに注入します。これが実際の例です。

app.controller('firstCtrl', function($scope, $rootScope) {        
        function firstCtrl($scope) {
        {
            $rootScope.$emit('someEvent', [1,2,3]);
        }
}

app.controller('secondCtrl', function($scope, $rootScope) {
        function secondCtrl($scope)
        {
            $rootScope.$on('someEvent', function(event, data) { console.log(data); });
        }
}

$scope オブジェクトにリンクされたイベントは、所有者コントローラーでのみ機能します。コントローラー間の通信は、$rootScope またはサービスを介して行われます。

于 2016-01-10T07:01:39.450 に答える
7

プロミスを返すコントローラーからサービスを呼び出して、それをコントローラーで使用できます。さらに$emitor$broadcastを使用して、他のコントローラーに通知します。私の場合、サービスを介して http 呼び出しを行う必要があったため、次のようにしました。

function ParentController($scope, testService) {
    testService.getList()
        .then(function(data) {
            $scope.list = testService.list;
        })
        .finally(function() {
            $scope.$emit('listFetched');
        })


    function ChildController($scope, testService) {
        $scope.$on('listFetched', function(event, data) {
            // use the data accordingly
        })
    }

私のサービスは次のようになります

    app.service('testService', ['$http', function($http) {

        this.list = [];

        this.getList = function() {
            return $http.get(someUrl)
                .then(function(response) {
                    if (typeof response.data === 'object') {
                        list = response.data.results;

                        return response.data;
                    } else {
                        // invalid response
                        return $q.reject(response.data);
                    }

                }, function(response) {
                    // something went wrong
                    return $q.reject(response.data);
                });

        }

    }])
于 2014-03-20T11:19:37.833 に答える
4
<!DOCTYPE html>
<html>

<head>
<script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script>
var app = angular.module('MyApp',[]);
app.controller('parentCtrl',function($scope){
  $scope.$on('MyEvent',function(event,data){    
    $scope.myData = data;
  });
 });

app.controller('childCtrl',function($scope){
  $scope.fireEvent = function(){ 
  $scope.$emit('MyEvent','Any Data');
  }  
 });
</script>
</head>
<body ng-app="MyApp">
<div ng-controller="parentCtrl" ng-model="myName">

{{myData}}

 <div ng-controller="childCtrl">
   <button ng-click="fireEvent()">Fire Event</button>
 </div>

</div>
</body>
</html>
于 2015-04-13T13:25:38.587 に答える
4

これは私の機能です:

$rootScope.$emit('setTitle', newVal.full_name);

$rootScope.$on('setTitle', function(event, title) {
    if (scope.item) 
        scope.item.name = title;
    else 
        scope.item = {name: title};
});
于 2014-09-11T10:37:05.463 に答える
2

以下のコードは、イベントが上位の親コントローラー (rootScope) にディスパッチされる場所から 2 つのサブコントローラーを示しています。

<body ng-app="App">

    <div ng-controller="parentCtrl">

        <p>City : {{city}} </p>
        <p> Address : {{address}} </p>

        <div ng-controller="subCtrlOne">
            <input type="text" ng-model="city" />
            <button ng-click="getCity(city)">City !!!</button>
        </div>

        <div ng-controller="subCtrlTwo">

            <input type="text" ng-model="address" />
            <button ng-click="getAddrress(address)">Address !!!</button>

        </div>

    </div>

</body>

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

// parent controller
App.controller('parentCtrl', parentCtrl);

parentCtrl.$inject = ["$scope"];

function parentCtrl($scope) {

    $scope.$on('cityBoom', function(events, data) {
        $scope.city = data;
    });

    $scope.$on('addrBoom', function(events, data) {
        $scope.address = data;
    });
}

// sub controller one

App.controller('subCtrlOne', subCtrlOne);

subCtrlOne.$inject = ['$scope'];

function subCtrlOne($scope) {

    $scope.getCity = function(city) {

        $scope.$emit('cityBoom', city);    
    }
}

// sub controller two

App.controller('subCtrlTwo', subCtrlTwo);

subCtrlTwo.$inject = ["$scope"];

function subCtrlTwo($scope) {

    $scope.getAddrress = function(addr) {

        $scope.$emit('addrBoom', addr);   
    }
}

http://jsfiddle.net/shushanthp/zp6v0rut/

于 2015-05-08T14:36:56.790 に答える