繁体   English   中英

指令之间通信的最佳方式

[英]Best way for communication between directives

这里复制。 可能是,我可以在这里得到更正确的答案!

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

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

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

require:父指令

内部指令可以要求外部指令,它可以在其控制器上公开某些方法。 所以在内在的定义

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

在外部指令的控制器中:

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

$ emit事件

内部指令可以$ $发出一个事件,外部指令可以通过$ on响应。 所以在内部指令的控制器中:

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>

所以内部控制器有一个可以调用的“innerChoose”函数

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

这将调用(在这种情况下)外部指令范围内的'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) {
  }
}

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

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

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

首先,我想指出你的例子

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

是不会合作的

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

您需要使用$ parse运行整个innerChoose表达式,或者您只需要传递对该函数的引用,例如:

<outer>
  <inner inner-choose="functionOnOuter"></inner>
  <inner inner-choose="functionOnOuter"></inner>
</outer>

除此之外,它还归结为基于团队的风格偏好以及您需要完成的内容最有意义的内容。 例如,如果您需要能够执行基于JSON中的数据而设置的命令,这些数据基于可以以不同方式组合在一起的多个层而事先不知道,那么您可能需要使用事件,因为任何耦合完全可以阻止您在正确的数据上创建或执行正确的命令。

如果您需要执行的主要任务是构建利用该功能的视图,您可能希望使用共享的$ scope来保持视图尽可能简单。

我主要只使用require for ngModel,它更像兄弟指令而不是父指令。 我还没有用于需要引用整个父控制器的用例。

当我们有这样的层次结构时,我会选择第一个选项。 创建require以紧密耦合两个指令或组件(来自Angular 1.5)。 你可以用它来指出你不能在没有outer情况下使用inner

我不是事件的粉丝,因为当我们使用错误时,他们可以经历许多范围。

&和范围设置有一些优点,但这取决于你想要什么。 这些并不适用于所有情况。

我认为现在在这样的讨论中我们应该考虑Angular 2。 如果要从子组件执行函数,则需要使用@ViewChild批注传递此组件。 我认为Angular 1.x中最接近的解决方案是使用require,它(如我所提到的)也是为Angular 1.x组件实现的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM