我创建了一个dropdownToggle
指令,其功能如下:
toggle()
isOpen()
open()
close()
closeAll()
除了现在我有一点问题,它们都完美无缺。我需要从另一个指令中调用closeAll()
函数。
原因是我的主要内容区域附加了一个click
事件监听器,需要关闭所有当前打开的下拉面板/菜单。
如何实现这一目标?我正在考虑将所有这些函数移到service
中,但如果可能的话,我更愿意将DOM操作保留在指令中。
答案 0 :(得分:4)
这是一个典型的情况,你需要一个指令来增加另一个指令的行为。
根据 the docs ,指令定义对象的控制器属性是您所需要的:
<强>控制器强>
控制器构造函数。控制器在预链接阶段之前被实例化,并与其他指令共享(请参阅require属性)。这允许指令彼此通信并增强彼此的行为。控制器是可注射的(并支持括号表示法),具有以下本地:
- $ scope - 与元素相关的当前范围
- $ element - 当前元素
- $ attrs - 元素的当前属性对象
- $ transclude - 预先绑定到正确的转换范围的转换链接函数。范围可以由可选的第一个参数覆盖。 function([scope],cloneLinkingFn)。
为了能够访问第一个指令的控制器,你需要require
来自第二个指令:
.directive('directive1', function () {
return {
...
controller: function ($scope, $element, $attrs) {
this.doSomething = function () {
alert('Directive1: Done something !');
};
},
...
};
});
.directive('directive2', function () {
return {
...
require: 'directive1',
link: function postLink(scope, elem, attrs, dir1Ctrl) {
scope.doSomething = dir1Ctrl.doSomething;
}
};
});
另请参阅此 short demo 。
答案 1 :(得分:0)
您可以在指令的控制器中指定您的功能,然后从另一个指令中请求它。另一种方法是emit
或broadcast
自定义事件,您将在目标控制器中进行侦听。
如果您不了解它们,请查看egghead.io上的教程,它们对我来说很有启发性。特别是,这个问题完全解决了您的问题:
答案 2 :(得分:0)
该服务是一个选项,它不必须进行DOM操作。指令的实例(或任何其他有兴趣参与此行为的指令)可以在要通知的服务中注册自己。服务本身只会执行通知部分。
如果只是通知,则可以使用$rootScope
上的活动来完成,即为此目的使用$rootScope.$on()
和$rootScope.$emit()
。
在任何情况下,不要忘记在$destroy
上取消注册监听器:$scope.$on("$destroy", function() { /*unregister listener here*/ })
(提示:scope.$on()
返回注销功能)。