嵌套指令之间的通信


61

指令之间似乎有很多通信方式。假设您有嵌套指令,内部指令必须将某些内容传递给外部指令(例如,它是由用户选择的)。

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

通过执行父作用域中的表达式 &

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

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

因此,inner控制器具有可以调用的“ innerChoose”功能

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

这将在outer指令的范围内调用(在这种情况下)“ functionOnOuter”函数:

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

非隔离范围上的范围继承

鉴于这些是嵌套的控制器,范围继承可以起作​​用,并且内部指令可以调用范围链中的任何函数(只要它没有隔离的范围)。因此,在inner指令中:

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

并在outer指令中:

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

通过服务注入内部和外部

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

问题:彼此之间有哪些潜在的弊端和优势?


5
我不敢相信我之前从未见过这个问题。感谢您提供的所有选项。如果您尚未这样做,您是否考虑过将这个问题发布在stackoverflow上?我希望它将对stackoverflow产生更多的吸引力。
Mike Barlow-BarDev 2014年

Answers:


7

我的首选是&在指令范围内定义属性,这主要是因为我将指令的scope: {}定义视为其API。查看作用域属性定义以查看指令正确运行所需的信息比搜索$emit'd事件,继承的作用域函数或注入的控制器中使用的函数的链接和控制器函数要容易得多。


1

我的意见:

服务是跨模块/指令/控制器共享行为/数据的首选方式。指令是可以嵌套或不嵌套的孤立事物。控制器应尽可能多地坚持作为视图模型,理想情况下,任何业务逻辑都不应在那里结束。

所以:

当您开始通过访问父作用域函数将它们连接在一起时,我认为您可能会以太硬的方式将它们耦合在一起,并使整个应用程序不可读且组件不可重用。当您将共享数据或行为在服务中解耦时,您将受益于将整个指令重用不同的数据/行为,甚至可以确定在运行时要使用的服务。依赖注入到底是什么。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.