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

Javascript 在另一个指令中重用指令函数,javascript,angularjs,Javascript,Angularjs,我创建了一个dropdownttoggle指令,它具有如下功能: toggle() isOpen() open() close() closeAll() 它们都很好用,只是现在我有点小问题。我需要从另一个指令调用closeAll()函数 原因是我的主要内容区域附带了一个单击事件侦听器,需要关闭所有当前打开的下拉面板/菜单 如何做到这一点?我正在考虑将所有这些函数移动到服务中,但如果可能的话,我更愿意在指令中保留DOM操作。您可以在指令的控制器中指定您的函数,然后从另一个指令中要求它。另一种方法

我创建了一个
dropdownttoggle
指令,它具有如下功能:

toggle()
isOpen()
open()
close()
closeAll()
它们都很好用,只是现在我有点小问题。我需要从另一个指令调用
closeAll()
函数

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


如何做到这一点?我正在考虑将所有这些函数移动到
服务中,但如果可能的话,我更愿意在指令中保留DOM操作。

您可以在指令的控制器中指定您的函数,然后从另一个指令中要求它。另一种方法是
发出
广播
自定义事件,您将在目标控制器中收听该事件

如果你不认识他们,请查看上的教程,它们对我很有启发。特别是,这一条正好解决了您的问题:


您可以在指令的控制器中指定您的功能,然后从另一个指令中要求它。另一种方法是
发出
广播
自定义事件,您将在目标控制器中收听该事件

如果你不认识他们,请查看上的教程,它们对我很有启发。特别是,这一条正好解决了您的问题:


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

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


在任何情况下,不要忘记在
$destroy
$scope.$on(“$destroy”,function(){/*unregister listener here*/})
(提示:
scope.$on()
返回注销函数)。

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

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


在任何情况下,不要忘记在
$destroy
$scope.$on(“$destroy”,function(){/*unregister listener here*/})
(提示:
scope.$on()
返回注销函数)。

这是一种典型情况,您需要一个指令来增强另一个指令的行为。
根据,指令定义对象的控制器属性是您需要的:

控制器
控制器构造函数。控制器在预链接阶段之前实例化,并与其他指令共享(请参见require属性)。这允许指令彼此通信并增强彼此的行为。控制器是可注入的(并支持括号表示法),具有以下局部变量:

  • $scope—与元素关联的当前范围
  • $element-当前元素
  • $attrs-元素的当前属性对象
  • $transclude-一个预先绑定到正确转换范围的转换链接函数。范围可以由可选的第一个参数覆盖。函数([scope],克隆链接fn)

为了访问第一条指令的控制器,您需要从第二条指令访问它:

.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;
        }
    };
});

另请参见,这是一个典型的情况,您需要一个指令来增强另一个指令的行为。
根据,指令定义对象的控制器属性是您需要的:

控制器
控制器构造函数。控制器在预链接阶段之前实例化,并与其他指令共享(请参见require属性)。这允许指令彼此通信并增强彼此的行为。控制器是可注入的(并支持括号表示法),具有以下局部变量:

  • $scope—与元素关联的当前范围
  • $element-当前元素
  • $attrs-元素的当前属性对象
  • $transclude-一个预先绑定到正确转换范围的转换链接函数。范围可以由可选的第一个参数覆盖。函数([scope],克隆链接fn)

为了访问第一条指令的控制器,您需要从第二条指令访问它:

.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;
        }
    };
});

另请参见此

您不需要从根范围发出/广播,因为指令也可以访问范围。在一般情况下,指令可能位于层次结构中的任何位置。它们的作用域可能是同级,在这种情况下,
$emit
-ing/
$broadcast
-ing不会传输事件
emit
-ing在
$rootScope
上实现了两件事:它们都得到了消息,因为只有一个
$rootScope
,并且涉及的作用域数量最少,希望将性能损失降到最低(
$emit
-ing/
$broadcast
-ing在任何其他情况下,内部作用域都会影响其父级或子级;
$rootScope
没有父级转发
$emit
-ed事件,因此它会留在那里)。你是对的,我没有考虑同级事件。你不需要emit/broadc