[英]AngularJS communication between directives
我是Angular.js的新手,我需要在我的應用程序之間進行指令之間的一些通信,我閱讀了一些關於鏈接和需求的文檔,但是無法准確理解它是如何工作的。
我有一個簡單的例子:活小提琴: http : //jsfiddle.net/yw235n98/5/
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.$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
才能將事件啟用到應用程序中的不同節點。 您可以在應用程序中輕松構建pub / sub機制,並使用原型繼承。
在這里,我在應用程序初始化期間在$rootScope's
原型上添加了2個方法publish
和subscribe
。 因此,任何子范圍或隔離范圍都將提供這些方法,並且通信將變得如此簡單,而不必擔心是否使用$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);
並且可以在應用程序的任何地方收聽,而無需擔心使用$rootScope
或$emit
或$broadcast
: -
$scope.subscribe('eventName', function(data){
//do somthing
});
從您的示例中,指令結構不是父子。 因此,您無法通過其控制器共享方法。 我會使用$rootScope.$broadcast
。 (見DOCS )
一條指令稱:
$rootScope.$broadcast('someEvent', [1,2,3]);
第二個指令偵聽:
scope.$on('someEvent', function(event, mass) {
console.log(mass)}
);
演示小提琴
固定指令:
app.directive("firstDir", function ($rootScope) {
return {
restrict: 'E',
link: function (scope, element, attrs) {
scope.dataToPass = 'empty';
scope.doClick = function (valueToPass) {
scope.dataToPass = valueToPass;
$rootScope.$broadcast('someEvent', {
data: valueToPass
});
}
}
};
});
app.directive("secondDir", function () {
return {
restrict: 'E',
link: function (scope, element, attrs) {
scope.receivedData = 'none';
scope.$on('someEvent', function (event, result) {
scope.receivedData = result.data;
});
}
}
});
我正在使用的是導出指令控制器。 假設我有以下指令:
app.directive('mainDirective', function () {
return {
require: 'mainDirective'
restrict: 'E',
scope: {
controller: '='
},
controller: [
'$scope',
function ($scope) {
// controller methods
this.doSomething = function () { ... },
$scope.controller = this
return this
}
],
link: function (scope, element, attrs, mainDirective) {
// some linking stuff
}
}
});
我的HTML看起來像這樣:
<main-directive controller="mainDirective"></main-directive>
<sub-directive main-directive="mainDirective"></sub-directive>
如果我想從子指令控制main-directive,我可以很容易地從它的范圍中獲取它並做我想做的事......
app.directive('subDirective', function () {
return {
restrict: 'E',
scope: {
mainDirective: '='
}
link: function (scope, element, attrs) {
// do something with main directive
scope.mainDirective.doSomething();
}
}
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.