Ответ 1
Один из способов общения между ними, используя так называемый eventing.
Одна директива может испускать событие на корнетопере, которое затем может слушать любой, кто хочет. Вы можете использовать $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
, чтобы включить eventing в другой node в вашем приложении. Вместо этого вы можете создать паб/вспомогательный механизм, который легко встроен в ваше приложение и использовать прототипное наследование.
Здесь я добавляю 2 метода 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);
и слушать в любом месте приложения, не беспокоясь об использовании $rootScope
или $emit
или $broadcast
: -
$scope.subscribe('eventName', function(data){
//do somthing
});