独立管理独立AngularJS指令之间的通信

时间:2012-11-30 05:10:42

标签: angularjs

这更像是解决此问题的组织方法,而不是直接解决方案。我的问题本身就是如果我有两个指令不相互依赖,并且可以独立工作以达到其目的。但是如果其中一个指令存在,那么另一个指令需要在另一个指令就绪后执行。在这种情况下,那么在不需要对任何函数调用或事件进行硬编码的情况下确保以这种方式工作的逻辑方法是什么?

让我们假设您有一个指令可以构建某种类型的网格:

angular.module('App').directive('appGrid',function() {
  return function($scope, element) {
    $scope.rows = ...
  };
});

然后我有另一个指令使元素可以水平滚动:

angular.module('App').directive('appPane',function() {
  return function($scope, element) {
    element.attachHorizontalScroll();
  };
});

所以我的HTML示例如下:

<div data-app-grid data-app-pane>
  <div data-ng-repeat="row in rows">
    <div data-ng-repeat="cell in row.cells">
      {{ cell.data }}
    </div>
  </div>
</div>

基本上appPane指令需要在执行appGrid指令并且表准备就绪后运行。

我能想到的一个解决方案是使用$scope.$watch方法观察数据以查看它何时就绪,但这会产生问题,因为更改可能会多次发生,这将是冗余更新的糟糕设计如果多个指令正在写入正在监视的同一范围变量,那么页面也会出现问题。

另一个解决方案是让第一个指令发出一个事件(类似于elementReady),然后让第二个指令接管。但是,如果第一个指令不存在呢?那么第二指令怎么会知道什么时候做它的工作呢?可能有另一个指令基本上是一个空指令,只是为所有其他元素触发事件,但这是一个黑客攻击。如果多个其他指令触发elementReady事件会发生什么?

另一个解决方案是创建第3个指令,该指令通过共享服务在两个指令之间共享逻辑。但这使得第3指令完全依赖于其他指令以及它们之间的共享服务。这还需要更多,不必要的测试代码以及​​编写指令的实际代码(与第二个解决方案相比,代码要多得多,只需要一行+一行代码)。

有什么想法吗?

3 个答案:

答案 0 :(得分:3)

查看指令的优先级属性。

以下是角度文档的确切描述的副本:

  

priority - 当在单个DOM元素上定义了多个指令时,有时需要指定其中的顺序   指令适用。优先级用于排序   调用它们的编译函数之前的指令。优先级更高   先走了。指令的顺序在同一优先级内   未定义。

你应该能够在

中找到它

http://docs.angularjs.org/guide/directive

编写指令(长版) --- 指令定义对象部分。

希望这能回答你的问题。

答案 1 :(得分:3)

我有类似的问题。我无法使用优先级,因为点击元素后发生了布线。我用$ rootScope解决了它。这是一个简化的例子:

link : function (scope, element, attrs) {
   element.on('click', function() {
       $rootScope.$emit('myEvent', myData);
   });
}

在另一个指令中,你'监听' myEvent

link : function (scope, element, attrs) {
   $rootScope.$on('myEvent', function(data) {
      // do sth
   });
}

答案 2 :(得分:1)

好问题。我会使用属性和事件的组合。

由于只有指令的用户(即编写HTML的人)知道他/她想要两个指令进行交互(即依赖运行),我认为他/她需要以某种方式指定这一点,并且属性似乎是一种好方法(唯一的方法?)。一旦指令知道他们需要进行交互,他们就可以使用事件来进行信令。

因此,如果指令B需要等待指令A,则可以使用一个或多个属性来指定谁应该进行等待,谁应该触发事件,和/或事件名称是什么。 (当然,这可以扩展到两个以上的指令和多个事件。)一些可能的实现:

<div data-app-grid data-app-pane idc-wait="appPane" idc-event="idc-appGridDone">
<div data-app-grid data-app-pane idc-wait="appPane" idc-emit="appGrid" idc-event="idc-appGridDone">

通过检查属性,appGrid指令可以确定它不需要等待,但它确实需要发出事件“idc-appGridDone”。同样,通过检查属性,appPane指令可以确定它在运行之前需要等待“idc-appGridDone”事件。

如果指令没有找到任何这些特殊的“指令间通信”/“idc-”属性,它们就会正常运行(没有事件,没有等待)。

“依赖于指令间的通信模式”诞生了。 ☺