javascript - 嵌套指令之间的不同通信方式

标签 javascript angularjs angularjs-directive

似乎有很多指令之间的通信方式。假设您有嵌套指令,其中内部指令必须与外部指令进行通信(例如,它已由用户选择)。

<outer>
  <inner></inner>
  <inner></inner>
</outer>

到目前为止,我有 5 种方法可以做到这一点

require:父指令

inner 指令可以要求 outer 指令,它可以在其 Controller 上公开一些方法。所以在内部定义

require: '^outer',
link: function(scope, iElement, iAttrs, outerController) {
   // This can be passed to ng-click in the template
   $scope.chosen = function() {
     outerController.chosen(something);
   }
}

outer 指令的 Controller 中:

controller: function($scope) {
   this.chosen = function(something) {
   }
}

$emit 事件

inner 指令可以$emit 一个事件,outer 指令可以通过$on 响应该事件>。所以在 inner 指令的 Controller 中:

controller: function($scope) {
  $scope.chosen = function() {
    $scope.$emit('inner::chosen', something);
  }
}

outer 指令 Controller 中:

controller: function($scope) {
  $scope.$on('inner::chosen, function(e, data) {
  }
}

在父作用域中执行表达式,通过&

该项目可以绑定(bind)到父作用域中的表达式,并在适当的点执行它。 HTML 会是这样的:

<outer>
  <inner inner-choose="functionOnOuter(item)"></inner>
  <inner inner-choose="functionOnOuter(item)"></inner>
</outer>

所以 inner Controller 有一个可以调用的 'innerChoose' 函数

scope: {
  'innerChoose': '&'
},
controller: function() {
  $scope.click = function() {
    $scope.innerChoose({item:something});
  }
}

这将调用(在本例中)outer 指令范围内的“functionOnOuter”函数:

controller: function($scope) {
  $scope.functionOnOuter = function(item) {
  }
}

非隔离作用域的作用域继承

鉴于这些是嵌套的 Controller ,作用域继承可以起作​​用,并且内部指令可以调用作用域链中的任何函数,只要它没有独立的作用域)。所以在 inner 指令中:

// scope: anything but a hash {}
controller: function() {
  $scope.click = function() {
    $scope.functionOnOuter(something);
  }
}

outer 指令中:

controller: function($scope) {
  $scope.functionOnOuter = function(item) {
  }
}

通过服务同时注入(inject)内部和外部

服务可以注入(inject)到两个指令中,因此它们可以直接访问同一个对象,或者调用函数来通知服务,甚至可以在发布/订阅系统中注册自己以接收通知。这不需要嵌套指令。

问题:与其他相比,它们各自的潜在缺点和优点是什么?

致谢/免责声明:这不是我的问题,我找到了 original question on programmers .original author从来没有按照建议将它移到这里。

最佳答案

感谢指出原作者

以下是我认为应该优先考虑的每种情况:

使用require父指令if

  • 内总是在外
  • 内部总是调用相同的外部 API
  • 内部是私有(private)的,开发者与外部进行交互

使用 $emit 事件如果

  • 这两个指令没有任何共同点,尤其是层次结构
  • 沟通的需要依赖于一个事件
  • 你懒得为它创建服务

通过& if

在父作用域中执行表达式
  • inner 不需要总是 inside outer
  • 内部并不总是从外部或使用相同的参数调用相同的 API

在非隔离作用域上使用作用域继承,如果

不,不要。它与使用 require 相同,只是您不保证 inner 会在 outer 之内,并且对于程序员来说如何使用该指令变得非常不清楚。

使用注入(inject)到内部和外部的服务 if

  • 你的情况与 $emit 情况相同
  • 但你是个好人

就是这样。服务总是比广播好,因为它明确地告诉程序员哪些事件对指令有影响。大多数情况下,使用 $emit 之类的东西确实是最糟糕的选择,因为它的行为就像许多开发人员讨厌的老式 goto 表达式:you will当您有太多事件时,很难尝试调试您的指令。

现在,如果层次结构得到保证并且 API 得到修复,我建议使用 require,因为使用指令的开发人员可以少一些担心。

关于javascript - 嵌套指令之间的不同通信方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29991257/

相关文章:

javascript - 发现由于验证错误,表单未发布到服务器

javascript - 将指令属性分配给模板中的元素

javascript - 在 Angular Directive(指令)上提交表单之前更改输入值

AngularJS 和 contentEditable 两种方式绑定(bind)无法按预期工作

javascript - 创建 ID 不相互跟随的父子树 JSON

javascript - 在 jquery 中绑定(bind)按键,无需插件

jquery - 尝试删除所有 ng 选项值时,Select 中的 Angular JS 空白选项

javascript - AngularJS 中出现 CORS 错误

javascript - 将静态问题转化为动态问题

angularjs - ng-Repeat ng-show 如果前一个项目字段值不同