Javascript 自定义角度指令广播事件,但不广播嵌套子级?
我已经在Angular中创建了一个accorbian指令,它可以嵌套,所以accorbian可以在其中包含子accorbian 我想在手风琴打开和关闭时广播一个事件,以便其他指令可以监听它(例如,打开手风琴面板内部的菜单时,它可能会显示自己) 问题是,如果外部元素中有嵌套的内部accorbian,我不希望事件被广播到内部accorbian的子元素,因为内部accorbian没有广播打开/关闭事件 以防这没有意义,换一种方式说,嵌套的accordian中的元素应该能够侦听它所在的accordian所广播的打开/关闭事件,而不是DOM树上的一个 希望有一个简单的解决办法 更新:在此处添加了演示: 很明显,我还没有正确理解$broadcast和$on,因为演示活动目前根本不起作用,但应该清楚我在尝试做什么 编辑:显然,所有指向JSFIDLE的链接都必须附带代码,所以这里有一些Javascript 自定义角度指令广播事件,但不广播嵌套子级?,javascript,angularjs,angularjs-directive,angular-broadcast,Javascript,Angularjs,Angularjs Directive,Angular Broadcast,我已经在Angular中创建了一个accorbian指令,它可以嵌套,所以accorbian可以在其中包含子accorbian 我想在手风琴打开和关闭时广播一个事件,以便其他指令可以监听它(例如,打开手风琴面板内部的菜单时,它可能会显示自己) 问题是,如果外部元素中有嵌套的内部accorbian,我不希望事件被广播到内部accorbian的子元素,因为内部accorbian没有广播打开/关闭事件 以防这没有意义,换一种方式说,嵌套的accordian中的元素应该能够侦听它所在的accordian
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' });
});
}
};
});
您可以添加一个数值
depth
或类似于您的广播,该数值定义了广播发送的层次深度。如果正在侦听的指令控制器的深度
大于1
,则可以执行。否则它可以忽略广播
如果不清楚,我还可以添加一个小示例,请告诉我。到目前为止,最简单的方法是使用您在评论中提到的
require
解决这个问题的一种方法是注册子控制器(甚至它们的回调函数),然后父控制器可以调用每个子控制器,而不是广播
这里需要注意的是,您需要require:“?^^parent”
-这意味着,将require设置为可选的,并且严格地说是祖先选择器;对于“^”
Angular将返回self
.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');
}
看看这篇修改过的文章。这里有一些代码很有帮助,比如你的事件的名称,你从哪个范围广播/收听,等等……对不起,这里可能有太多的代码要发布,把它删减以制作JSFIDLE将是一个挑战。我可以随意调用这些事件,因为它们目前不存在,并假设我将从我创建的手风琴指令中播放它们。老实说,这不一定是关于我的手风琴指令,这更像是一个关于热的一般性问题,在链的下游广播一个事件,但当你到达一个相同类型的指令时停止。好吧,老实说,由于收件人不能取消
$broadcast
,所以你刚才描述的场景不容易建模。最简单的方法可能是以编程方式生成用于事件名称的字符串键,并以某种方式将该值传递给需要侦听的元素,以便每个手风琴都是唯一的。谢谢,这很有意义。我觉得$broadcast不能取消。我目前正在探索在子元素上使用require:^accorbian,并让它们注册回调或使用accorbian,而不是在阅读本文时使用$broadcast/$onIssue,这听起来比较复杂,但解决方案可能相对简单。我真的不知道用一个简化的演示来模拟它需要多长时间,而为了更好地理解您正在使用的东西,创建这个演示也不需要多长时间。。。垃圾输入,垃圾输出如果有帮助的话,我刚刚添加了一个JSFIDLE。谢谢,但是当您将对$broadcast的调用包装在$scope中时,为什么它不起作用。$apply(),为什么您需要创建一个外部函数?实际上,如果您这样做,它就起作用了$scope.$apply(函数(){$element.scope().$broadcast('panelOpened');})。。。但是如果您使用$scope.$broadcast(),则它必须是$element.scope()。$broadcast()谢谢,我想我可以修改此代码并使其工作。实际上,当手风琴打开时,需要做出反应的不是亚手风琴,而是另一个指令,需要它并注册回调,这样我就不必担心“自我”问题,我只需要把registerChild和notify函数放在accorbian上,把handleNotification放在另一个指令上,该指令正在accorbian上注册。