1

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

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

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

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

要求:父指令

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

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) {
  }
}

通过服务注入内部和外部

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

问题:与其他人相比,每个人都有哪些潜在的缺点和优点?

4

2 回答 2

2

首先,我想指出你的例子

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

不适合

范围: {
  'innerChoose': '&'
},
控制器:函数(){
  $scope.click = 函数() {
    $scope.innerChoose({item:something});
  }
}

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

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

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

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

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

于 2016-05-31T15:49:54.090 回答
1

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

我不喜欢事件,因为当我们使用错误时,它们可能会经过很多范围。

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

我认为现在在这样的讨论中,我们应该考虑 Angular 2。如果你想从子组件执行一个函数,你需要使用 @ViewChild 注释传递这个组件。我认为 Angular 1.x 中最接近的解决方案是使用 require,它(正如我已经提到的)也适用于 Angular 1.x 组件。

于 2016-05-31T15:53:06.390 回答