自定义 Angular 指令广播事件但不广播到嵌套子级?



我在 Angular 中创建了一个可以嵌套的手风琴指令,因此手风琴可以在其中包含子手风琴。

我想在手风琴打开和关闭时扩展一个事件,以便其他指令可以侦听它(例如,手风琴面板内的菜单可能会在手风琴内部打开时显示出来)。

问题是,如果外部手风琴内部有一个嵌套的内部手风琴,我不希望事件广播到内部手风琴的子元素,因为内部手风琴没有广播打开/关闭事件。

以防万一这毫无意义,换句话说,嵌套手风琴中的元素应该能够侦听它所在的手风琴广播的打开/关闭事件,而不是 DOM 树上更远的手风琴。

希望有一个简单的解决方案。

更新:在此处添加了演示:http://jsfiddle.net/jonhobbs/xr1kLqba/

我显然没有正确理解$broadcast和$on,因为演示活动目前根本不起作用,但应该清楚我想做什么!

编辑:显然所有指向jsfiddle的链接都必须附带代码,所以这里有一些。

var app = angular.module('app', []);
app.controller('MainCtrl', function($scope) {
$scope.mainMenuOpen = true;
})
.directive('myPanel', function() {
return {
restrict: 'EA',
scope: {
isOpen: '=?'
},
link: function($scope, $element, $attrs) {  
$element.find('> BUTTON').bind('click', function() {
$scope.isOpen = !$scope.isOpen;
if ($scope.isOpen) {
$scope.$broadcast('panelOpened');
}
});
}
};
})
.directive('reactToPanelOpenClose', function() {
return {
restrict: 'EA',
scope: {},
link: function($scope, $element, $attrs) {
$scope.$on('panelOpened', function() {
alert("clicked");
$element.css({ 'background-color': 'red' });
});
}
};
});

到目前为止,最简单的方法是使用您在评论中提到的require

解决此问题的一种方法是注册子控制器(甚至它们的回调函数),然后父控制器可以调用每个子控制器而不是广播。

这里要注意的是,你需要require: "?^^parent"- 意思是,使require成为可选的和严格的祖先选择器;因为"^"Angular将返回自身。

.directive("accordion", function(){
return {
require: ["accordion", "?^^accordion"],
controller: function(){
var children = [];
this.registerChild = function(childCtrl){
children.push(childCtrl);
}
this.handleNotification = function(){
// do something when notification arrives from parent
}
this.notify = function(){
angular.forEach(children, function(child){
child.handleNotification();
})
}
},
link: function(scope, element, attrs, ctrls){
var me = ctrls[0], parent = ctrls[1];
if (parent){
parent.registerChild(me);
} 
}
}
})

你正在尝试在 jQuery 回调中使用角度上下文,所以这是行不通的。解决问题的最简单方法是以下代码片段:

angular.$externalBroadcast = function (element, event, data) {
var scope = element.scope();
scope.$apply(function () {
scope.$broadcast(event, data);
});
};

并在面板指令的链接函数中应用此功能:

$scope.isOpen = !$scope.isOpen;                
if($scope.isOpen){
angular.$externalBroadcast($element, 'panelOpened');
}

看看这个修改过的小提琴。

您可以添加一个与广播depth或类似的数字值,用于定义发送广播的分层深度。 如果指令控制器侦听,depth更高1,则可以执行。否则,它可以忽略广播。

如果不清楚,我也可以添加一个小例子,请告诉我。

相关内容

  • 没有找到相关文章

最新更新