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

Javascript 嵌套指令之间通信的不同方式,javascript,angularjs,angularjs-directive,Javascript,Angularjs,Angularjs Directive,指令之间的通信方式似乎有很多种。假设您有嵌套指令,其中内部指令必须与外部指令通信(例如,它是由用户选择的) 在外部指令的控制器中: controller: function($scope) { this.chosen = function(something) { } } controller: function($scope) { $scope.chosen = function() { $scope.$emit('inner::chosen', something)

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

外部
指令的控制器中:

controller: function($scope) {
   this.chosen = function(something) {
   }
}
controller: function($scope) {
  $scope.chosen = function() {
    $scope.$emit('inner::chosen', something);
  }
}
controller: function($scope) {
  $scope.$on('inner::chosen, function(e, data) {
  }
}
$emit
事件
内部
指令可以
$emit
一个事件,
外部
指令可以通过
$on
响应该事件。因此在
内部
指令的控制器中:

controller: function($scope) {
   this.chosen = function(something) {
   }
}
controller: function($scope) {
  $scope.chosen = function() {
    $scope.$emit('inner::chosen', something);
  }
}
controller: function($scope) {
  $scope.$on('inner::chosen, function(e, data) {
  }
}
外部
控制器中:

controller: function($scope) {
   this.chosen = function(something) {
   }
}
controller: function($scope) {
  $scope.chosen = function() {
    $scope.$emit('inner::chosen', something);
  }
}
controller: function($scope) {
  $scope.$on('inner::chosen, function(e, data) {
  }
}
通过
&
该项可以绑定到父范围中的表达式,并在适当的点执行它。HTML将类似于:

<outer>
  <inner inner-choose="functionOnOuter(item)"></inner>
  <inner inner-choose="functionOnOuter(item)"></inner>
</outer>
在本例中,它将调用
外部
指令作用域上的'functionOnOuter'函数:

controller: function($scope) {
  $scope.functionOnOuter = function(item) {
  }
}
非隔离作用域上的作用域继承 如果这些是嵌套的控制器,那么作用域继承可以起作用,并且内部指令可以只调用作用域链中的任何函数,只要它没有隔离的作用域)。因此在
内部
指令中:

// scope: anything but a hash {}
controller: function() {
  $scope.click = function() {
    $scope.functionOnOuter(something);
  }
}
controller: function($scope) {
  $scope.functionOnOuter = function(item) {
  }
}
外部
指令中:

// scope: anything but a hash {}
controller: function() {
  $scope.click = function() {
    $scope.functionOnOuter(something);
  }
}
controller: function($scope) {
  $scope.functionOnOuter = function(item) {
  }
}
通过向内部和外部注入服务 一个服务可以被注入到两个指令中,这样它们就可以直接访问同一个对象,或者调用函数来通知服务,甚至可以在发布/订阅系统中注册自己以获得通知。这不需要嵌套指令

问题:两者相比,有哪些潜在的缺点和优点


信用/免责声明:这不是我的问题,我找到了。他们从未按照建议将其移到这里。

感谢您向原作者指出

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

如果需要,请使用
require
parent指令
  • 内在总是外在的
  • 内部始终调用相同的外部API
  • 内部是私有的,开发者与外部互动
如果需要,请使用$emit事件
  • 这两个指令没有任何共同之处,尤其是层次结构
  • 沟通的需要取决于事件
  • 您觉得太懒了,无法为它创建服务
在父作用域中执行表达式,如果
  • 内部不需要总是在内部和外部
  • 内部并不总是从外部调用相同的API,或者使用相同的参数
在以下情况下对非隔离作用域使用作用域继承 不,不要。这与使用
require
相同,只是您不能保证inner将在outer中,而且对于程序员来说,如何使用该指令变得非常不清楚

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

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


现在,如果层次结构得到了保证,API得到了修复,我建议使用
require
,因为使用指令的开发人员不用担心这个问题。

只想指出指令交互的另一种方式-通过对象:

<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>

IMHO,我更喜欢require:parent指令和在父范围内执行表达式,通过&。推荐的方法是使用“在父范围内通过&.执行表达式”。仅在没有其他选项时使用$emit。