在 Angular 1.5 组件中使用 $emit

Posted

技术标签:

【中文标题】在 Angular 1.5 组件中使用 $emit【英文标题】:Using $emit in angular 1.5 component 【发布时间】:2016-09-14 11:29:43 【问题描述】:

我正在使用 Angular 1.5 组件,需要从子组件中的 $emit 开始调用父控制器中的函数。我们如何做到这一点?

例子:

(function (angular) 
    'use strict';

    controllerName.$inject = [];

    function controllerName() 
       var _this = this;
       function toBeCalledOnEmit() //some code
       var vm = 
          toBeCalledOnEmit: toBeCalledOnEmit
       
       angular.extend(_this, vm);
    

    angular.module('moduleName', [
    ]).component('parentComponenet', 
        templateUrl: 'templateUrl',
        controller: 'controllerName'
    ).controller('controllerName', controllerName);

)(angular);

子组件:

(function (angular) 
    'use strict';

    childController.$inject = [];

    function childController() 
       //needs $emit here
    

    angular.module('childModuleName', [
    ]).component('childComponent', 
        templateUrl: 'templateUrl',
        controller: 'childController'
    ).controller('childController', childController);

)(angular);

【问题讨论】:

我在 1.5 之前使用过 $emit、$broadcast 和 $on,但是在 1.5 组件中我们没有使用 $scope 或 $rootscope。如何在没有 $scope 的情况下实现这一目标?在文档中,$emit 与 $scope 一起使用。 【参考方案1】:

我更喜欢使用公开订阅和通知功能的单独事件服务。但如果你更喜欢从子组件发出,那么它看起来像这样:

子组件

    (function (angular) 
    'use strict';

      function childController($scope) 
       $scope.$emit("someEvent", args); 
      

      angular.module('childModuleName', [
      ]).component('childComponent', 
        templateUrl: 'templateUrl',
        controller: ['$scope', childController]
      );

    )(angular);

父组件

    (function (angular) 
    'use strict';


      function controllerName($scope) 
         var _this = this;

         function toBeCalledOnEmit(event, args) 
            //some code
         
         $scope.on('someEvent', toBeCalledOnEmit);

         var vm = 
            toBeCalledOnEmit: toBeCalledOnEmit
         
         angular.extend(_this, vm);
      

      angular.module('moduleName', [
      ]).component('parentComponent', 
          templateUrl: 'templateUrl',
          controller: ['$scope', controllerName]
      );

    )(angular);

【讨论】:

当我们想要一个通知和订阅的地方时,像@Praveen Poonia 那样使用 $rootScope 是一个好主意(尽管据我所知,$rootScope 和 $scope 将在 Angular 2 中被弃用)。 我不建议使用$rootScope。在做了一些阅读之后,这似乎是内存泄漏的可能性。有关详细信息,请参阅here。 this 未定义.. 见这里:***.com/q/48691233/766570 angular.extend() 部分有什么作用?它只是绑定事件有效负载,使其成为父组件上的属性...?【参考方案2】:

代码附在下面:

    子组件:

    (function (angular) 
        'use strict';
    
    childController.$inject = ['$scope'];
    
    function childController($scope) 
    
       //needs $emit here
    $scope.$emit("topic-123", 'any message'); 
    
    
    angular.module('childModuleName', [
    ]).component('childComponent', 
        templateUrl: 'templateUrl',
        controller: 'childController'
    ).controller('childController', childController);
    

    )(角度);

    父组件:

    (function (angular) 
    'use strict';
    
    controllerName.$inject = ['$scope'];
    
    function controllerName($scope) 
       var _this = this;
       function toBeCalledOnEmit() //some code
       var vm = 
          toBeCalledOnEmit: toBeCalledOnEmit
       
    
       $scope.$on('topic-123', function(event, msg) 
      // @TODO  
      toBeCalledOnEmit();
       );
    
       angular.extend(_this, vm);
    
    
    angular.module('moduleName', [
    ]).component('parentComponenet', 
        templateUrl: 'templateUrl',
        controller: 'controllerName'
    ).controller('controllerName', controllerName);
    

    )(角度);

【讨论】:

【参考方案3】:

您可以使用 $rootScope 来执行此操作。在我的情况下它工作正常 -

子组件:

(function (angular) 
 'use strict';

 childController.$inject = ['$rootScope'];

 function childController($rootScope) 
   $rootScope.$emit('myEvent',$scope.data)
 
)(angular);

父组件:

(function (angular) 
 'use strict';

 controllerName.$inject = ['$rootScope'];

 function controllerName($rootScope) 
   var _this = this;
   function toBeCalledOnEmit() //some code
   var vm = 
      toBeCalledOnEmit: toBeCalledOnEmit
   
   $rootScope.$on('myEvent', function(event, msg) 
     toBeCalledOnEmit();
   );
   angular.extend(_this, vm);
 
)(angular);

【讨论】:

以上是关于在 Angular 1.5 组件中使用 $emit的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Angular 1.5 中使用 HTML 选择调用父组件

如何在 Angular 1.5 中将 Angular 组件与 ui.bootstrap.modal 一起使用?

如何在 Angular 1.5 组件中使用多槽透入,或者改用啥?

如何在 Angular 1.5 中注入组件路由器?

Angular 1.5 组件依赖注入

如何在 Angular 1.5 组件中使用绑定