Я пытаюсь дать одному ребенку указание сообщить своему родному брату, что информация обновлена.
У меня есть эта разметка:
<rp-nav>
<rp-nav-item cat="1"></rp-nav-item>
<rp-nav-item cat="2"></rp-nav-item>
<rp-nav-item cat="3"></rp-nav-item>
<rp-flyout></rp-flyout>
</rp-nav>
<hr>
<rp-nav>
<rp-nav-item cat="one"></rp-nav-item>
<rp-nav-item cat="two"></rp-nav-item>
<rp-nav-item cat="three"></rp-nav-item>
<rp-flyout></rp-flyout>
</rp-nav>
Я использую события таким образом:
angular.module('rpNavItem', [])
.directive('rpNavItem', function() {
return {
restrict: 'E',
controller: function($scope) {},
controllerAs: 'ctrl',
bindToController: true,
// scope: true,
template: function(el, attrs) {
return '<div>Item ' + attrs.cat + '</div>';
},
link: function(scope, el, attrs, ctrl) {
el.on('click', function(){
scope.$broadcast('selectedCat', attrs.cat);
});
}
};
});
angular.module('rpFlyout', []).directive('rpFlyout', function() {
return {
restrict: 'E',
controllerAs: 'ctrl',
bindToController: true,
// scope:true,
controller: function($scope) {},
template: '<p style="background-color: lightblue">{{category}}</p>',
link: function(scope) {
scope.$on('selectedCat', function(event, value){
scope.category = value;
scope.$digest();
console.log(value);
});
}
};
});
Проблема в том, что каждый раз, когда я нажимаю на один элемент, оба всплывающих окна получают обновление, и я просто хочу, чтобы соответствующий обновлялся. Как я могу это достичь? Является ли это правильным способом передачи информации между двумя директивами сестры, заключенными внутри родительской изолированной области?
Каждая область изолята является дочерней из одного и того же $rootScope
поэтому вы не можете использовать события для разделения директив. $broadcast
-ed используются для глобальной (до корневой) связи.
Чтобы напрямую связываться с директивами, вы можете использовать свойство require
для директив, поэтому rpNavItem
может потребовать rpNav
и использовать rpNav
для совместного использования.
Для этого примера не требуется rpFlyout
, javascript:
angular.module('app', ['rpNav']);
angular.module('rpNav', [])
.directive('rpNav', function() {
return {
scope: true,
controller: ['$scope', function ($scope) {
this.setSelectedCat = function (cat) {
$scope.category = cat;
}
}]
};
});
angular.module('rpNav')
.directive('rpNavItem', function() {
return {
restrict: 'E',
scope: {
cat: '@'
},
template: function (el, attrs) {
return '<div>Item ' + attrs.cat + '</div>';
},
require: '^rpNav',
link: function (scope, el, attrs, rpNav) {
el.on('click', function(){
scope.$apply(function () {
rpNav.setSelectedCat(scope.cat);
});
});
}
};
});
HTML может стать чем-то вроде:
<div rp-nav>
<rp-nav-item cat="1"></rp-nav-item>
<rp-nav-item cat="2"></rp-nav-item>
<rp-nav-item cat="3"></rp-nav-item>
<p style="background-color: lightblue">{{category}}</p>
</div>
<hr>
<div rp-nav>
<rp-nav-item cat="one"></rp-nav-item>
<rp-nav-item cat="two"></rp-nav-item>
<rp-nav-item cat="three"></rp-nav-item>
<p style="background-color: lightblue">{{category}}</p>
</div>
Если вы хотите сохранить директиву rpFlyout
по какой-либо причине, вы можете сделать это и изолированным хранилищем и передать текущую категорию в атрибут (непроверенный код):
<rp-flyout category="category"></rp-flyout>
Директива:
[...]
.directive('rpFlyout', function() {
return {
scope: {
'category': '='
},
template: '<p style="background-color: lightblue">{{category}}</p>'
};
});