在angular 1.5组件中使用$emit
在angular 1.5组件中使用$emit
我正在使用Angular 1.5组件,并且需要在子组件中使用$emit来调用父控制器中的函数。我们该如何实现呢?\n示例代码:\n
(function (angular) { 'use strict'; controllerName.$inject = []; function controllerName() { var _this = this; function toBeCalledOnEmit() {//一些代码} var vm = { toBeCalledOnEmit: toBeCalledOnEmit } angular.extend(_this, vm); } angular.module('moduleName', []).component('parentComponenet', { templateUrl: 'templateUrl', controller: 'controllerName' }).controller('controllerName', controllerName); })(angular);
\n子组件:\n
(function (angular) { 'use strict'; childController.$inject = []; function childController() { //在这里需要使用$emit } angular.module('childModuleName', []).component('childComponent', { templateUrl: 'templateUrl', controller: 'childController' }).controller('childController', childController); })(angular);
使用$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组件中,无法直接使用父组件向子组件传递数据的方法。因此,需要使用$rootScope来实现组件之间的通信。
解决方法是:在子组件中使用$rootScope的$emit方法来发送一个自定义事件,然后在父组件中使用$rootScope的$on方法来监听该事件,并执行相应的回调函数。这样就实现了父子组件之间的数据传递和通信。在上述代码中,子组件通过$rootScope.$emit('myEvent',$scope.data)发送了一个名为'myEvent'的自定义事件,并传递了$scope.data作为参数。而父组件则通过$rootScope.$on('myEvent', function(event, msg) {})来监听'myEvent'事件,并在事件触发时执行相应的回调函数。
在上述代码中,有一个问题是子组件(childComponent)需要向父组件(parentComponent)发送消息。子组件中使用了$scope.$emit来发送消息,而父组件中使用了$scope.$on来接收消息。然而,这两个组件之间没有建立联系,因此子组件发送的消息无法被父组件接收到。
为了解决这个问题,我们可以使用$rootScope来建立子组件和父组件之间的联系。在子组件中,将$scope.$emit更改为$rootScope.$emit;在父组件中,将$scope.$on更改为$rootScope.$on。这样,子组件发送的消息就可以被父组件接收到了。
下面是修改后的代码:
- 子组件:
(function (angular) { 'use strict'; childController.$inject = ['$scope', '$rootScope']; function childController($scope, $rootScope) { // 需要使用$rootScope.$emit $rootScope.$emit("topic-123", 'any message'); } angular.module('childModuleName', []).component('childComponent', { templateUrl: 'templateUrl', controller: 'childController' }).controller('childController', childController); })(angular);
- 父组件:
(function (angular) { 'use strict'; controllerName.$inject = ['$scope', '$rootScope']; function controllerName($scope, $rootScope) { var _this = this; function toBeCalledOnEmit() { // some code } var vm = { toBeCalledOnEmit: toBeCalledOnEmit } $rootScope.$on('topic-123', function(event, msg) { // toBeCalledOnEmit(); _this.toBeCalledOnEmit(); // 修改为使用controller的方法 }); angular.extend(_this, vm); } angular.module('moduleName', []).component('parentComponenet', { templateUrl: 'templateUrl', controller: 'controllerName' }).controller('controllerName', controllerName); })(angular);
问题的原因是在Angular 1.5组件中使用$emit时遇到了一些困难,需要找到解决方法。下面是解决方法:
首先,我们可以使用一个独立的事件服务来订阅和通知事件。但如果更喜欢从子组件中发出事件,代码如下:
子组件
(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);
在一些阅读中发现,像Poonia那样使用$rootScope是个好主意,因为我们希望有一个单一的地方来通知和订阅事件(尽管据我所知,$rootScope和$scope将在Angular 2中被弃用)。
不建议使用$rootScope。经过一些阅读,发现可能会导致内存泄漏。详情请参见这里。
this
是未定义的。请参见stackoverflow.com/q/48691233/766570。
angular.extend()
是做什么的?它只是将事件数据绑定到父组件的属性上吗?