AngularJS 指令之间的通信 [英] AngularJS communication between directives

查看:22
本文介绍了AngularJS 指令之间的通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 Angular.js 的新手,我的应用程序需要在指令之间进行一些通信,我阅读了一些关于链接和要求的文档,但无法确切理解它是如何工作的.

I'am new to Angular.js, I need for my application some communication between directives, I read some documentation about link and require, but can't understand exactly how it works.

举一个简单的例子,我有:live fiddle:http://jsfiddle.net/yw235n98/5/

For a simple example I have : live fiddle : http://jsfiddle.net/yw235n98/5/

  • 2 条指令:firstDir, secondDir :: 带有一些数据
  • firstDir 有一个点击函数可以改变数据值
  • 当触发 firsDir 单击功能时,我也想更改 secondDir 中的数据.

HTML:

<body ng-app="myApp">
First Directive :   
<first-dir >
    <h3>{{firstCtrl.data}}</h3>
    <button ng-click="firstCtrl.set('NEW VALUE')">Change Value</button>
</first-dir>
Second Directive : 
<second-dir>
    <h3>{{secondCtrl.data}}</h3>
</second-dir>

Javascript:

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

    app.directive("firstDir", function(){
        return {
            restrict : 'E',
            controller : function(){        
                this.data = 'init value';
                this.set = function(value){
                    this.data = value;
                    // communication with second Directive ???
                }       
            },
            controllerAs : 'firstCtrl'
        };  
    });

    app.directive("secondDir", function(){
        return {
            restrict : 'E',
            controller : function(){        
                this.data = 'init value';   
            },
            controllerAs : 'secondCtrl'
        };  
    });
})();

推荐答案

一种可以使用称为事件的方式在它们之间进行通信的方式.

One way you can communicate between them using what is called eventing.

一个指令可以在 rootscope 上发出一个事件,然后任何人都可以收听该事件.您可以使用 $rootScope.$emit$rootScope.$broadcast 发布带有数据的事件并使用 $scope.$on 来收听事件.在您的情况下,您也可以执行 $scope.$emit .

One directive can emit an event on the rootscope which can then be listened by anybody who wants to. You could use $rootScope.$emit or $rootScope.$broadcast to publish events with data and use $scope.$on to listen to the event. In your case you could just do $scope.$emit as well.

app.directive("firstDir", function(){
    return {
        restrict : 'E',
        controller : function($scope){        
            this.data = 'init value';

            this.set = function(value){
             //EMIT THE EVENT WITH DATA
              $scope.$emit('FIRST_DIR_UPDATED', value);
                this.data = value;
                // communication with second Directive ???
            }       
        },
        controllerAs : 'firstCtrl'
    };  
});

app.directive("secondDir", function(){
    return {
        restrict : 'E',
        controller : function($scope){    
          var _that = this;
          //LISTEN TO THE EVENT 
          $scope.$on('FIRST_DIR_UPDATED', function(e, data){
                 _that.data = data;
          });
          this.data = 'init value';   
        },
        controllerAs : 'secondCtrl'
    };  
});

演示Demo2

____________________________________________________________________________

现在说到这一点,有时确实需要注入 $rootScope 只是为了在应用程序中为不同的节点启用事件.相反,您可以在您的应用程序中轻松构建发布/订阅机制,并利用原型继承.

Now speaking of which, it sometimes is really required to inject $rootScope just to have the eventing enabled to a different node in your application. You can instead have a pub/sub mechanism easily built in your app and make use of prototypical inheritance.

在这里,我在应用程序初始化期间在 $rootScope's 原型上添加了 2 个方法 publishsubscribe.因此,任何子作用域或隔离作用域都可以使用这些方法,通信将变得更加容易,无需担心是否使用 $emit$broadcast,是否需要注入$rootscope 用于从隔离作用域指令等进行通信

Here i am adding 2 methods publish and subscribe on $rootScope's prototype during app initialization. So any child scope or isolated scope will have these methods available and communication will be so easier without worrying about whether to use $emit, $broadcast, whether i need to inject a $rootscope for communication from isolated scoped directive etc.

app.service('PubSubService', function () {


   return {Initialize:Initialize};

     function Initialize (scope) {
        //Keep a dictionary to store the events and its subscriptions
        var publishEventMap = {};

         //Register publish events
          scope.constructor.prototype.publish =  scope.constructor.prototype.publish 
           || function () {
                var _thisScope = this,
                    handlers, 
                    args, 
                    evnt;
                //Get event and rest of the data
                args = [].slice.call(arguments);
                evnt = args.splice(0, 1);
                //Loop though each handlerMap and invoke the handler
                angular.forEach((publishEventMap[evnt] || []), function (handlerMap) {
                    handlerMap.handler.apply(_thisScope, args);
                })
            }

         //Register Subscribe events
         scope.constructor.prototype.subscribe = scope.constructor.prototype.subscribe 
            || function (evnt, handler) {
                var _thisScope = this,
                    handlers = (publishEventMap[evnt] = publishEventMap[evnt] || []);

                //Just keep the scopeid for reference later for cleanup
                handlers.push({ $id: _thisScope.$id, handler: handler });
              //When scope is destroy remove the handlers that it has subscribed.  
             _thisScope.$on('$destroy', function () {
                for(var i=0,l=handlers.length; i<l; i++){
                  if (handlers[i].$id === _thisScope.$id) {
                        handlers.splice(i, 1);
                        break;
                    }
                }
            });
        }

    }
}).run(function ($rootScope, PubSubService) {
    PubSubService.Initialize($rootScope);
});

并且您可以让您的应用程序中的任何位置发布事件而无需 rootScope.

and you could just have any place from your app publish an event without requiring a rootScope.

$scope.publish('eventName', data);

并在应用程序的任何地方收听而不必担心使用 $rootScope$emit$broadcast:-

and listen anywhere on the application without worrying about using $rootScope or $emit or $broadcast:-

$scope.subscribe('eventName', function(data){
    //do somthing
});

演示 - PubSub

这篇关于AngularJS 指令之间的通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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