为了账号安全,请及时绑定邮箱和手机立即绑定

指令之间的AngularJS通信

/ 猿问

指令之间的AngularJS通信

繁花如伊 2019-11-14 10:18:40

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


对于一个简单的例子,我有:live小提琴: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'

        };  

    });

})();


查看完整描述

3 回答

?
烧仙草VB

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


一个指令可以在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种方法publish并subscribe在$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

});


查看完整回答
反对 回复 2019-11-14
?
弑天下

在您的示例中,指令结构不是父子结构。因此,您无法通过其控制器共享方法。我会用$rootScope.$broadcast。(请参阅DOCS)


一个指令调用:


$rootScope.$broadcast('someEvent', [1,2,3]);

第二条指令侦听:


 scope.$on('someEvent', function(event, mass) {

    console.log(mass)}

  );


固定指令:


app.directive("firstDir", function ($rootScope) {

    return {

        restrict: 'E',

        link: function (scope, element, attrs) {

            scope.dataToPass = 'empty';

            scope.doClick = function (valueToPass) {

                scope.dataToPass = valueToPass;

                $rootScope.$broadcast('someEvent', {

                    data: valueToPass

                });

            }

        }

    };

});


app.directive("secondDir", function () {

    return {

        restrict: 'E',

        link: function (scope, element, attrs) {

            scope.receivedData = 'none';


            scope.$on('someEvent', function (event, result) {

                scope.receivedData = result.data;

            });

        }

    }

});


查看完整回答
反对 回复 2019-11-14
?
饮歌长啸

我正在使用的是导出指令控制器。假设我有以下指令:


app.directive('mainDirective', function () {

  return {

    require: 'mainDirective'

    restrict: 'E',

    scope: {

      controller: '='

    },

    controller: [

      '$scope',

      function ($scope) {

        // controller methods

        this.doSomething = function () { ... },


        $scope.controller = this

        return this

      }

    ],

    link: function (scope, element, attrs, mainDirective) {

      // some linking stuff

    }

  }

});

我的html看起来像这样:


<main-directive controller="mainDirective"></main-directive>

<sub-directive main-directive="mainDirective"></sub-directive>

如果我想从子指令控制主指令,我可以轻松地从它的作用域中获取它并做我想做的任何事情...


app.directive('subDirective', function () {

  return {

    restrict: 'E',

    scope: {

      mainDirective: '='

    }

    link: function (scope, element, attrs) {

      // do something with main directive

      scope.mainDirective.doSomething();

    }

  }

});


查看完整回答
反对 回复 2019-11-14

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信