javascript - 指令之间通信的最佳方式

标签 javascript angularjs design-patterns angularjs-directive angularjs-events

复制自here .也许,我可以在这里得到更合适的答案!

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

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

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

要求:父指令

内部指令可以要求外部指令,它可以在其 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);
   }
}

在外部指令的 Controller 中:

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

$发射事件

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

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

在外部指令 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>

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

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

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

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

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

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

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

在外部指令中:

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

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

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

问题:相对于其他的,它们有哪些潜在的缺点和优点?

最佳答案

首先,我想指出你的例子

<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 中的数据设置的命令,这些数据基于可以以不同方式组合在一起的多个层而事先不知道,您可能需要使用事件,因为任何耦合根本无法阻止您对正确的数据创建或执行正确的命令。

如果您需要做的主要任务是构建利用该功能的 View ,您可能希望使用共享 $scope 以使 View 尽可能简单。

我主要只对 ngModel 使用 require,它更像是一个兄弟指令而不是父指令。我还没有需要引用整个父 Controller 的用例。

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

相关文章:

java - 在 Java 中实现单例模式的有效方法是什么?

java - 数据模型应该包含 Controller 吗? (MVC)

javascript - 如何在 jQuery 对话框中获取 ActionLink 参数

angularjs - 如何指定时区到日期过滤器

javascript - 命名文本区域不会以 Angular 形式创建实例

java - 如何在 java 中实现委托(delegate)模式(如在 objective-c 中)

javascript - 如何从 jQuery 中的变量中删除换行符和空格

javascript - 如何在输入文本字段 HTML 中添加序列号

javascript - 将javascript添加到wordpress页面

javascript - 为在 Angular 下拉列表中创建的默认空白选项设置占位符文本?