$ on和$angular度广播

我有一个footerController和codeScannerController与不同的意见。

angular.module('myApp').controller('footerController', ["$scope", function($scope) {}]); angular.module('myApp').controller('codeScannerController', ["$scope", function($scope) { console.log("start"); $scope.startScanner = function(){... 

当我点击footer.html中的<li> ,我应该在codeScannerController中得到这个事件。

 <li class="button" ng-click="startScanner()">3</li> 

我认为可以通过$on$broadcast来实现,但是我不知道如何在任何地方find示例。

如果你想$broadcast使用$rootScope

 $scope.startScanner = function() { $rootScope.$broadcast('scanner-started'); } 

然后接收,使用您的控制器的$scope

 $scope.$on('scanner-started', function(event, args) { // do what you want to do }); 

如果你希望你可以传递参数,当你$broadcast

 $rootScope.$broadcast('scanner-started', { any: {} }); 

然后收到他们:

 $scope.$on('scanner-started', function(event, args) { var anyThing = args.any; // do what you want to do }); 

范围文档中的文档 。

首先, $on()$broadcast()$emit()的简短描述:

  • .$on(name, listener) – 通过一个给定的name监听一个特定的事件
  • .$broadcast(name, args) – 通过所有孩子的$scope向下广播一个事件
  • .$emit(name, args) – 向$scope层次结构中的所有父项发出一个事件,包括$rootScope

基于以下HTML(请参阅完整示例 ):

 <div ng-controller="Controller1"> <button ng-click="broadcast()">Broadcast 1</button> <button ng-click="emit()">Emit 1</button> </div> <div ng-controller="Controller2"> <button ng-click="broadcast()">Broadcast 2</button> <button ng-click="emit()">Emit 2</button> <div ng-controller="Controller3"> <button ng-click="broadcast()">Broadcast 3</button> <button ng-click="emit()">Emit 3</button> <br> <button ng-click="broadcastRoot()">Broadcast Root</button> <button ng-click="emitRoot()">Emit Root</button> </div> </div> 

触发的事件将遍历$scopes ,如下所示:

  • 广播1 – 只会被控制器1 $scope看到
  • 发射1 – 将被控制器1 $scope然后$rootScope看到
  • 广播2 – 将看到控制器2 $scope然后控制器3 $scope
  • 发射2 – 将被控制器2 $scope然后$rootScope看到
  • 广播3 – 只能被控制器3 $scope看到
  • 发射3 – 将被控制器3 $scope ,控制器2 $scope然后$rootScope看到
  • 广播根(Root) – 将被所有控制器的$rootScope$scope所看到(1,2和3)
  • 发射根 – 只能被$rootScope看到

JavaScript来触发事件(再次,你可以在这里看到一个工作的例子 ):

 app.controller('Controller1', ['$scope', '$rootScope', function($scope, $rootScope){ $scope.broadcastAndEmit = function(){ // This will be seen by Controller 1 $scope and all children $scopes $scope.$broadcast('eventX', {data: '$scope.broadcast'}); // Because this event is fired as an emit (goes up) on the $rootScope, // only the $rootScope will see it $rootScope.$emit('eventX', {data: '$rootScope.emit'}); }; $scope.emit = function(){ // Controller 1 $scope, and all parent $scopes (including $rootScope) // will see this event $scope.$emit('eventX', {data: '$scope.emit'}); }; $scope.$on('eventX', function(ev, args){ console.log('eventX found on Controller1 $scope'); }); $rootScope.$on('eventX', function(ev, args){ console.log('eventX found on $rootScope'); }); }]); 

有一件事你应该知道的是$前缀指的是一个Angular Method,$$前缀是指你应该避免使用的angular度方法。

下面是一个示例模板及其控制器,我们将探讨$ broadcast / $ on如何帮助我们实现我们想要的。

 <div ng-controller="FirstCtrl"> <input ng-model="name"/> <button ng-click="register()">Register </button> </div> <div ng-controller="SecondCtrl"> Registered Name: <input ng-model="name"/> </div> 

控制器是

 app.controller('FirstCtrl', function($scope){ $scope.register = function(){ } }); app.controller('SecondCtrl', function($scope){ }); 

我的问题是,当用户点击注册时,如何将名称传递给第二个控制器? 你可能会想出多个解决scheme,但是我们要使用的是使用$ broadcast和$ on。

$ broadcast vs $ emit

我们应该使用哪个? $ broadcast将传递给所有的孩子dom元素,$ emit将引导所有的祖先dom元素相反的方向。

避免在$ emit或$ broadcast之间做出决定的最好方法是从$ rootScope中引导并使用$ broadcast给它的所有子节点。 这使得我们的情况更容易,因为我们的dom元素是兄弟姐妹。

添加$ rootScope并让$ broadcast

 app.controller('FirstCtrl', function($rootScope, $scope){ $scope.register = function(){ $rootScope.$broadcast('BOOM!', $scope.name) } }); 

注意我们添加了$ rootScope,现在我们使用$ broadcast(broadcastName,arguments)。 对于broadcastName,我们想给它一个唯一的名字,以便我们可以在第二个Ctrl中捕获这个名字。 我select了BOOM! 只是为了好玩。 第二个参数“参数”允许我们将值传递给监听器。

收到我们的广播

在我们的第二个控制器中,我们需要设置代码来收听我们的广播

 app.controller('SecondCtrl', function($scope){ $scope.$on('BOOM!', function(events, args){ console.log(args); $scope.name = args; //now we've registered! }) }); 

这真的很简单。 现场示例

其他方法来达到类似的结果

尽量避免使用这套方法,因为它既不高效也不容易维护,但这是一个解决问题的简单方法。

通常可以通过使用服务或简化控制器来做同样的事情。 我们不会详细讨论这个问题,但我想我只是提到它的完整性。

最后,记住一个非常有用的广播是'$ destroy',你可以看到$表示它是由供应商代码创build的方法或对象。 反正$销毁是广播当一个控制器被摧毁,你可能想听听这个知道你的控制器被删除。

 //Your broadcast in service (function () { angular.module('appModule').factory('AppService', function ($rootScope, $timeout) { function refreshData() { $timeout(function() { $rootScope.$broadcast('refreshData'); }, 0, true); } return { RefreshData: refreshData }; }); }()); //Controller Implementation (function () { angular.module('appModule').controller('AppController', function ($rootScope, $scope, $timeout, AppService) { //Removes Listeners before adding them //This line will solve the problem for multiple broadcast call $scope.$$listeners['refreshData'] = []; $scope.$on('refreshData', function() { $scope.showData(); }); $scope.onSaveDataComplete = function() { AppService.RefreshData(); }; }); }());