6

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

例如,假设您有一个构建某种网格的指令:

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事件会发生什么?

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

有任何想法吗?

4

3 回答 3

3

查看指令的优先级属性。

这是角度文档中确切描述的副本:

优先级- 当在单个 DOM 元素上定义了多个指令时,有时需要指定应用指令的顺序。优先级用于在调用编译函数之前对指令进行排序。优先级更高。相同优先级内的指令顺序未定义。

你应该可以在

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

Writing directives (long version) --- Directives definition Object部分下。

希望这能回答你的问题。

于 2012-11-30T09:53:00.947 回答
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
   });
}
于 2012-12-20T10:56:03.943 回答
2

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

由于只有指令的用户(即编写 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-”属性,它们会正常运行(没有事件,没有等待)。

“(内)独立的指令间通信模式”诞生了。☺

于 2013-01-12T22:14:55.813 回答