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

时间:2015-05-01 16:50:58

标签: javascript angularjs angularjs-directive

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

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

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

require:父指令

inner指令可能需要outer指令,该指令可以在其控制器上公开某些方法。所以在inner定义中

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: function($scope) {
   this.chosen = function(something) {
   }
}

$emit事件

inner指令可以$emit outer指令可以通过$on响应的事件inner。所以在controller: function($scope) { $scope.chosen = function() { $scope.$emit('inner::chosen', something); } } 指令的控制器中:

outer

并在controller: function($scope) { $scope.$on('inner::chosen, function(e, data) { } } 指令控制器中:

&

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

在父作用域中执行表达式

该项可以绑定到父作用域中的表达式,并在适当的位置执行它。 HTML就像:

inner

所以scope: { 'innerChoose': '&' }, controller: function() { $scope.click = function() { $scope.innerChoose({item:something}); } } 控制器有一个'innerChoose'函数可以调用

outer

会在controller: function($scope) { $scope.functionOnOuter = function(item) { } } 指令的范围内调用(在本例中)'functionOnOuter'函数:

inner

非隔离范围的范围继承

鉴于这些是嵌套控制器,范围继承可以起作​​用,而内部指令只能调用范围链中的任何函数,只要它没有隔离的范围)。所以在// scope: anything but a hash {} controller: function() { $scope.click = function() { $scope.functionOnOuter(something); } } 指令中:

outer

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

{{1}}

通过注入内部和外部的服务

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

问题:每个人有什么潜在的缺点和优势?

信用/免责声明:这不是我的问题,我找到original question on programmersoriginal author从未按照建议将其移到此处。

2 个答案:

答案 0 :(得分:2)

感谢您向原作者指出。

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

如果

,请使用require父指令
  • 内心总是在外面
  • inner始终调用相同的外部API
  • 内部是私有的,开发者与外部
  • 交互

如果

,请使用$ emit事件
  • 这两个指令没有任何共同之处,尤其是层次结构
  • 沟通的需要依赖于事件
  • 你觉得懒得为它创建服务

通过& if

在父作用域中执行表达式
  • 内心并不总是在外面
  • 内部并不总是从外部调用相同的API,或使用相同的参数

如果

,则在非隔离范围上使用范围继承 不,不,不。它与使用require相同,除非你不保证内部将在外部,并且程序员如何使用该指令变得非常不清楚。

如果

,请使用注入内部和外部的服务
  • 您与$emit案例
  • 的情况相同
  • 但你是一个好人

关于它。服务总是比广播更好,因为它明确地告诉程序员哪些事件对指令有影响。使用$emit之类的东西在大多数情况下都是最好的选择,因为它的行为就像许多开发人员喜欢讨厌的旧学校goto表达一样:你会有一段糟糕的时间尝试当你有太多事件时调试你的指令。

现在,如果层次结构得到保证并且API已修复,我建议使用require,因为对于使用指令的开发人员来说,它不用担心。

答案 1 :(得分:0)

只想指出另一种指令进行交互 - 通过对象:

<outer model='model'>
  <inner model='model[0]'></inner>
  <inner model='model[1]'></inner>
</outer>

或更熟悉的案例:

<input type="checkbox" ng-model="smth"/>
<div ng-show="smth"></div>