在另一个指令中重用指令函数

时间:2014-05-21 11:35:30

标签: javascript angularjs

我创建了一个dropdownToggle指令,其功能如下:

toggle()
isOpen()
open()
close()
closeAll()

除了现在我有一点问题,它们都完美无缺。我需要从另一个指令中调用closeAll()函数。

原因是我的主要内容区域附加了一个click事件监听器,需要关闭所有当前打开的下拉面板/菜单。

如何实现这一目标?我正在考虑将所有这些函数移到service中,但如果可能的话,我更愿意将DOM操作保留在指令中。

3 个答案:

答案 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)

您可以在指令的控制器中指定您的功能,然后从另一个指令中请求它。另一种方法是emitbroadcast自定义事件,您将在目标控制器中进行侦听。

如果您不了解它们,请查看egghead.io上的教程,它们对我来说很有启发性。特别是,这个问题完全解决了您的问题:

egghead.io - Directive communication

答案 2 :(得分:0)

该服务是一个选项,它必须进行DOM操作。指令的实例(或任何其他有兴趣参与此行为的指令)可以在要通知的服务中注册自己。服务本身只会执行通知部分。

如果只是通知,则可以使用$rootScope上的活动来完成,即为此目的使用$rootScope.$on()$rootScope.$emit()

在任何情况下,不要忘记在$destroy上取消注册监听器:$scope.$on("$destroy", function() { /*unregister listener here*/ })(提示:scope.$on()返回注销功能)。