一尘不染

指令之间的AngularJS通信

javascript

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

  • 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'
        };  
    });
})();

阅读 227

收藏
2020-05-01

共1个答案

一尘不染

您可以使用事件方法在它们之间进行通信的一种方式。

一个指令可以在rootscope上发出一个事件,然后任何人都可以侦听。您可以使用$rootScope.$emit$rootScope.$broadcast发布带有数据的事件,并用于$scope.$on监听事件。就您而言,您也可以这样做$scope.$emit

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'
    };  
});

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

在这里,我将在应用初始化期间添加2种方法publishsubscribe$rootScope's原型上。所以,任何儿童范围或隔离的范围将这些方法可用,沟通会更容易因此无需担心是否使用$emit$broadcast我是否需要注入$rootscope从隔离范围的指令等进行通信

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。

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

并在应用程序的任何地方收听,而无需担心使用$rootScopeor $emit$broadcast:-

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