我是Angular.js的新手,我的应用程序需要指令之间的一些通信,我阅读了一些有关链接和需求的文档,但无法确切了解它的工作原理。
HTML:
<body ng-app="myApp"> First Directive : <first-dir > <h3>{{firstCtrl.data}}</h3> <button ng-click="firstCtrl.set('NEW VALUE')">Change Value</button> </first-dir> Second Directive : <second-dir> <h3>{{secondCtrl.data}}</h3> </second-dir>
Javascript:
(function(){ var app = angular.module('myApp', []); app.directive("firstDir", function(){ return { restrict : 'E', controller : function(){ this.data = 'init value'; this.set = function(value){ this.data = value; // communication with second Directive ??? } }, controllerAs : 'firstCtrl' }; }); app.directive("secondDir", function(){ return { restrict : 'E', controller : function(){ this.data = 'init value'; }, controllerAs : 'secondCtrl' }; }); })();
您可以使用事件方法在它们之间进行通信的一种方式。
一个指令可以在rootscope上发出一个事件,然后任何人都可以侦听。您可以使用$rootScope.$emit或$rootScope.$broadcast发布带有数据的事件,并用于$scope.$on监听事件。就您而言,您也可以这样做$scope.$emit。
$rootScope.$emit
$rootScope.$broadcast
$scope.$on
$scope.$emit
app.directive("firstDir", function(){ return { restrict : 'E', controller : function($scope){ this.data = 'init value'; this.set = function(value){ //EMIT THE EVENT WITH DATA $scope.$emit('FIRST_DIR_UPDATED', value); this.data = value; // communication with second Directive ??? } }, controllerAs : 'firstCtrl' }; }); app.directive("secondDir", function(){ return { restrict : 'E', controller : function($scope){ var _that = this; //LISTEN TO THE EVENT $scope.$on('FIRST_DIR_UPDATED', function(e, data){ _that.data = data; }); this.data = 'init value'; }, controllerAs : 'secondCtrl' }; });
现在讲,有时确实需要注入$rootScope只是为了将事件启用到应用程序中的其他节点。相反,您可以在自己的应用程序中轻松构建一个发布/订阅机制,并利用原型继承。
$rootScope
在这里,我将在应用初始化期间添加2种方法publish并subscribe在$rootScope's原型上。所以,任何儿童范围或隔离的范围将这些方法可用,沟通会更容易因此无需担心是否使用$emit,$broadcast我是否需要注入$rootscope从隔离范围的指令等进行通信
publish
subscribe
$rootScope's
$emit
$broadcast
$rootscope
app.service('PubSubService', function () { return {Initialize:Initialize}; function Initialize (scope) { //Keep a dictionary to store the events and its subscriptions var publishEventMap = {}; //Register publish events scope.constructor.prototype.publish = scope.constructor.prototype.publish || function () { var _thisScope = this, handlers, args, evnt; //Get event and rest of the data args = [].slice.call(arguments); evnt = args.splice(0, 1); //Loop though each handlerMap and invoke the handler angular.forEach((publishEventMap[evnt] || []), function (handlerMap) { handlerMap.handler.apply(_thisScope, args); }) } //Register Subscribe events scope.constructor.prototype.subscribe = scope.constructor.prototype.subscribe || function (evnt, handler) { var _thisScope = this, handlers = (publishEventMap[evnt] = publishEventMap[evnt] || []); //Just keep the scopeid for reference later for cleanup handlers.push({ $id: _thisScope.$id, handler: handler }); //When scope is destroy remove the handlers that it has subscribed. _thisScope.$on('$destroy', function () { for(var i=0,l=handlers.length; i<l; i++){ if (handlers[i].$id === _thisScope.$id) { handlers.splice(i, 1); break; } } }); } } }).run(function ($rootScope, PubSubService) { PubSubService.Initialize($rootScope); });
并且您可以在应用程序中的任何位置发布事件而无需rootScope。
$scope.publish('eventName', data);
并在应用程序的任何地方收听,而无需担心使用$rootScopeor $emit或$broadcast:-
$scope.subscribe('eventName', function(data){ //do somthing });