angular.js - angularjs中如何在两个控制器中实现实时通信?

【字号: 日期:2023-01-24浏览:24作者:雯心

问题描述

有两个控制器 a和b;在a控制器中有一个click事件,单击之后,怎样将b控制中的一个p显示出来?

举个例子:a控制器是菜单,b控制器是内容区,a中单击不同的菜单,b中要控制显示不同的内容,

一些努力:尝试了service和factory,只能共享数据,做不到实时触发

问题解答

回答1:

我这边尝试过两种:1.使用angular自己的事件机制

(function() { ’use strict’; angular.module(’app.core’).factory(’eventService’, eventService); /* @ngInject */ function eventService(logger) {var service = { on_angular_event: on_angular_event, trigger_angular_event: trigger_angular_event};return service;function on_angular_event(scope, type, f) { scope.$on(type, function(event, data){f(data);// 处理时间后阻止事件继续扩散event.stopPropagation = true; })}function trigger_angular_event(scope, deriction, type, data) { // deriction: up, down, sibling if (deriction === ’up’) {scope.$emit(type, data); } else if (deriction === ’down’){scope.$broadcast(type, data); } else if (deriction === ’sibling’){scope.$parent.$broadcast(type, data); }} }})();

在controller里面使用,加入a向b发事件通知:

controller_A.$inject = [$scope, eventService];function controller_A($scope, eventService) { //send event //direction 根据 A 和 B 的关系来定,父子用up或down,兄弟用sibling eventService.trigger_angular_event($scope, direction, ’event_name’, data);}controller_B.$inject = [$scope, eventService];function controller_B($scope, eventService) { // recv event from controller_A eventService.on_angular_event($scope, ’event_name’, function(data){// do something here });}

2.用service模拟回调事件,本质是用service保存了一个全局的回调函数供controller之间使用

(function() { ’use strict’; angular.module(’app.core’).factory(’eventService’, eventService); /* @ngInject */ function eventService(logger) {var onEventFunc = {};var service = { on: on, trigger: trigger};return service;function on(type, f) { onEventFunc[type] = onEventFunc[type] || []; var funcs = onEventFunc[type]; // Todo:同一个事件可以让不同的监听者监听,但是同一个监听者的回调只能注册一次。而回调函数多用匿名函数注册,此处用toString()进行区分,效率较低。 var exist = false; for (var i = 0; i < funcs.length; i++) {if (funcs[i].toString() === f.toString()) { exist = true; break;}; }; if (!exist) {funcs.push(f); };}function trigger(type, data) { //logger.info(’trigger’, data); for (var item in onEventFunc) {if (item === type) { var funcs = onEventFunc[item]; for (var i = 0; i < funcs.length; i++) {funcs[i](data); };}}} }})();回答2:

嗯。可以试试事件冒泡和隧道机制。

回答3:

可以看看这个

直接一点的可以尝试$broadcast和$on,但是效率会比较差

回答4:

看楼上写的不够纯粹(参杂其他考虑),我来补充下纯粹版。提供的 demo

代码如下

<!DOCTYPE html><html lang='en'><head> <meta charset='UTF-8'> <title></title></head><body ng-app='myApp'><p ng-controller='aCtrl'> <button type='button' ng-click='click()'>click</button></p><p ng-controller='bCtrl'> <p ng-if='showConfig.show'>will show me</p></p><script src='https://www.6hehe.com/bower_components/angular/angular.min.js'></script><script> // 通过事件,记得利用$rootScope 来广播事件。 // 优点是解耦,也是ng的一种通讯方式. 很容易理解 // 有人说什么性能差,效率不高之类的。 其实不是非常大的应用完全不用关注这个。 我理解就是一种js级冒泡。 性能远远小于dom操作。// angular.module(’myApp’, []).controller(’aCtrl’, function ($scope, $rootScope) {//$scope.click = function () {// $rootScope.$broadcast(’do_show’);//};// }).controller(’bCtrl’, function ($scope) {//$scope.showConfig = {// show: false//};//$scope.$on(’do_show’, function () {// $scope.showConfig.show = !$scope.showConfig.show;//})// });</script><script> // 利用ng双向绑定技术。 通过Service提供一个Scope,具备Scope的特性,利用这个Scope 把 aCtrl bCtrl 建立联系。 // angular.module(’myApp’, []).controller(’aCtrl’, function ($scope, $rootScope, Service) { //$scope.click = function () { // Service.showConfig.show = !Service.showConfig.show; //}; // }).controller(’bCtrl’, function ($scope, Service) { //// 注意这里是把Scope赋值。 而非 Service.showConfig.show 一个值赋值。 //$scope.showConfig = Service.showConfig; // }).factory(’Service’, function ($rootScope) { //var showConfig = $rootScope.$new(); //showConfig.show = false; //return { // showConfig: showConfig //}; // });</script><script></script></body></html>回答5:

1).来个事件总线,全局对所有的事件进行管理2).使用 $broadcast 和 $emit

相关文章: