通过独立作用域进行基于AngularJS事件的通信 [英] AngularJS event-based communication through isolate scope

查看:69
本文介绍了通过独立作用域进行基于AngularJS事件的通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在AngularJS中,一个指令如何使用基于事件的通信($emit$broadcast$on)与另一个具有隔离范围的指令进行通信?我已经创建了两个指令,并且当从第二个指令中删除了隔离范围时,第一个指令能够使用emit成功地与第二个指令进行通信.但是,将隔离作用域重新添加到第二个作用域后,通信就会中断.

In AngularJS, how can one directive use event-based communication ($emit, $broadcast and $on) to communicate with another directive which has an isolate scope? I've created two directives, and when the isolate scope is removed from the second directive, the first directive is able to use emit to successfully communicate with the second. However, when the isolate scope is added back to the second, communication breaks down.

var app = angular.module('myApp', []);

app.directive("firstDir", function() {
  return {
    restrict: 'E',
    controller: function($scope) {
      $scope.set = function() {
        $scope.$emit('MY_NEW_SEARCH', $scope.searchQuery);
      }       
    },
    template: '<input type="text" ng-model="searchQuery"><button ng-click="set()">Change Value</button>'
  };  
});

app.directive("secondDir", function() {
  return {
    restrict : 'E',
    scope: {},
    controller : function($scope) {    
      var _that = $scope;
      $scope.$on('MY_NEW_SEARCH', function(e, data) {
        _that.data = data;
      });
      $scope.data = 'init value';   
    }
  };  
});

我创建了一个Plunker来说明这个问题.您会注意到,如果注释掉第二条指令的指令定义对象中的"scope"属性,则通信将起作用:您可以在第一个指令的输入框中键入字符串,请按第一个指令的按钮指令,并将字符串传递给第二个指令,该指令将其显示在视图上. (按现状,由于隔离范围问题,Plunker损坏了,请参阅app.js文件的第19行.)

I've created a Plunker to illustrate the issue. You'll notice that if you comment out the "scope" property in the directive definition object of the second directive, communication works: You're able to type a string into the input box of the first directive, press the button of the first directive, and the string is communicated to the second directive, which displays it on the view. (As it stands, the Plunker is broken, because of the isolate scope issue, see line 19 of the app.js file.)

http://plnkr.co/edit/AXUVX9zdJx1tApDhgH32

这是我的总体目标:我对第二个指令使用隔离范围的原因是将内部范围与外部范围分开. (我的项目中使用的实际第二条指令"比这个玩具示例复杂得多.这就是必须这样做的原因.)我知道AngularJS提供了将外部作用域映射到指令的内部作用域的机制.我很好奇这些机制中的任何一种对于映射基于事件的通信的事件是否有用.

Here's my overarching goal: The reason I'm using an isolate scope for the second directive is to separate the scope inside from the scope outside. (The actual "second directive" used in my project is much more complex than this toy example. That's what makes this necessary.) I know AngularJS provides mechanisms for the mapping of the outer scope to a directive's inner scope. I'm curious if any of these mechanisms are useful for mapping the events of event-based communication.

如果答案是对于基于事件的通信来说,隔离作用域是无法克服的,那么在我已经说明的情况下,同时仍实现目标的情况下,实现指令到指令通信的最佳方法是什么?谢谢!

If the answer turns out to be that an isolate scope is insurmountable for event-based communication, what's the best way to accomplish directive to directive communication in the case which I've illustrated, while still accomplishing my goals? Thank you!

推荐答案

这来自两个问题.

1)第一个是因为两个指令在HTML中处于同一级别,所以您不能$emit从一个作用域到另一个作用域的事件(除非它们具有相同的作用域,第二个指令没有这种情况) t具有孤立的范围).

1) This first one is since both directives are on the same level in HTML, you cannot $emit an event from one scope to another (unless they have the same scope, which is the case when the second directive doesn't have an isolated scope).

为了使第一个指令与第二个指令联系,您可以将$scope.$emit(在作用域层次结构中向上)替换为$scope.$root.$broadcast(从根作用域向下至其所有子级),或者简单地$scope.$broadcast在您的情况下,因为第一个指令范围实际上是根范围!

In order for the first directive to contact the second, you can replace $scope.$emit (which goes upward in the scopes hierarchy) by $scope.$root.$broadcast (which goes downward from the root scope to all its children), or simply $scope.$broadcast in your case as this first directive scope is in fact the root scope!

2)第二个问题是您的第二个指令在隔离时无法按原样处理作用域转换,因此在DOM中更深处定义的HTML不会共享该指令隔离的作用域,但上面的那个却不能共享该指令. t定义data.

2) The second problem is that your second directive, when isolated, doesn't handle scope transclusion as is, so the HTML defined deeper in the DOM will not share that directive isolated scope, but the one above, which doesn't define data.

将隔离范围传播到内部HTML的方法是使用link函数中的以下代码段:

The way to propagate an isolated scope to the inner HTML is by using this snippet within the link function:

link: function(scope, element, attrs, ctrl, transclude) {
  transclude(scope, function(clone) {
    element.append(clone);
  });
}

这是同时具有两个修复功能的Plnker:

here is a working Plnker with both fixes:

http://plnkr.co/edit/I9Vmutal2gfqyLIU0iAe?p=preview

这篇关于通过独立作用域进行基于AngularJS事件的通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆