【问题标题】:communicating between directives controller指令控制器之间的通信
【发布时间】:2017-06-19 05:53:12
【问题描述】:

我知道如果我有两个嵌套的指令,我可以与 throw 控制器通信,require 并将其作为链接函数的第四个参数传递。

<my-first-div>
   <my-seconded-div></my-seconded-div>
</my-first-div>

一切都会正常工作。 但是当它们不嵌套时我可以做同样的事情。

<my-first-div></my-first-div>
<my-seconded-div></my-seconded-div>

为什么? 以及如何让他们交流?

【问题讨论】:

  • 希望this能帮到你
  • 使用服务共享来自 $rootScope 的数据或广播
  • 谢谢,我会试试的

标签: javascript angularjs angularjs-directive controller


【解决方案1】:

这是因为两个指令在同一个变量引用上都有观察者。因此,所有相关指令中都“注意到”了更改后的值。

您可以通过为两个指令传递相同的变量(通过引用)(varName:'=')来模拟这种“通信”,并在每个指令中放置对该变量的观察者。

那么,DOM 层次结构就无关紧要了

例如: 指令 1:

app.directive('directive1', function () {
  return {
    restrict: 'E',
    scope: {
      myVar: '='
    }
    link: function (scope, element, attrs) {
        // do something with main directive
        console.log("directive1", scope.myVar);

        $scope.$watch("scope.myVar", function (value) {
            console.log("directive1", "value changed to:" + scope.myVar)
        });
    }
   }
});

第二个指令也一样.. 对于两个指令都传递相同的变量 魔法就会发生

【讨论】:

    【解决方案2】:

    我假设所说的通信是指在两个指令之间共享数据、状态和事件。我将在这里列出我想到的基本方法:

    1. 之所以可以在两个嵌套指令之间传递数据/状态,是因为在 AngularJS 中,一个子指令(在您的示例中是嵌套的)继承了它的父指令的范围。因此,两个同级指令可以共享来自其父控制器的相同数据。

    <div ng-controller="ParentCtrl">
      <ng-sibling></ng-sibling>
      <ng-another-sibling></ng-another-sibling>
    </div> 

    在上面这段代码中,ng-siblingng-another-sibling 将继承在其父 ParentCtrl 中定义的相同数据强>

    1. AngularJS 支持使用 $broadcast、$emit 和 $on 函数发射/广播事件/数据,文档可以在这里找到:https://docs.angularjs.org/api/ng/type/$rootScope.Scope。

      $emit 可用于向上发送事件树的层次结构,而 $broadcast 向下发送,方向很重要。

      所以你的一个指令可以发送事件,而另一个监听它。和 jQuery 触发事件的方式非常相似。

    // In link function or controller of one directive
    $scope.$broadcast("EVENT_A",my_data);
    
    // Listen to EVENT_A on another directive
    $scope.$on("EVENT_A",function($event,data){
      ....
    })
    1. 虽然双向绑定或任意触发事件一开始可能很有用,但它们也可能导致很难跟踪应用程序的事件和数据流。如果你发现这种情况,也许考虑使用 Flux 架构和 AngularJS 不是一个坏主意。 Redux 完全支持 AngularJS,您的所有指令都可以构建为 single-state 组件。 Github repo 可以在这里找到:https://github.com/angular-redux/ng-redux,关于如何使用 Redux 运行 AngularJS 的简单教程可以在这里找到:http://blog.grossman.io/angular-1-using-redux-architecture/

    【讨论】:

    • 使用 $emit 和 $broadcast 我不会让自己暴露在太多数据或数据中吗?
    • 还有一件事我没有提到,我想在没有任何控制器的情况下这样做(不是出于任何原因,而是为了学习),所以你的第一个答案很好,但我试图避免它。我确实发现它可以通过 angular.element(element) 来完成,这让我可以直接接近我想要的侦探元素并访问它的范围。
    • 是的,通常情况下,指令/组件应该只暴露给它需要的特定数据。这并不意味着我说在共享范围/参考上使用它。范围引用应该是在应用程序指令之间传递数据的主要方式。同时,广播应该用于控制应用程序中的数据更新/更改,例如您可以使用 $broadcast 来指示其他组件在单击按钮后要做什么。
    • 关于你的第二条评论,基本上你不需要声明一个控制器,如果你不想。 AngularJs 本身中的任何指令都由控制器控制。 AngularJS 指令的三个主要部分是视图、控制器和观察者。我建议你研究一下关于指令的Angularjs文档以更好地理解它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-15
    • 1970-01-01
    • 2012-08-10
    • 1970-01-01
    • 2015-07-05
    • 2014-10-06
    相关资源
    最近更新 更多