有兩個控制器 a和b;在a控制器中有一個click事件,點擊之後,怎麼將b控制中的一個p顯示出來?
舉例:a控制器是選單,b控制器是內容區,a中點選不同的選單,b中要控制顯示不同的內容,
一些努力:嘗試了service和factory,只能共享數據,做不到實時觸發
业精于勤,荒于嬉;行成于思,毁于随。
我這邊嘗試過兩種: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); }; } } } } })();
嗯。可以試試事件冒泡和隧道機制。
可以看看這個
直接一點的可以嘗試$broadcast和$on,但是效率會比較差
看樓上寫的不夠純粹(參雜其他考慮),我來補充下純粹版。 提供的 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="../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>
1).來個事件匯流排,全域對所有的事件進行管理2).使用 $broadcast 和 $emit
我這邊嘗試過兩種:
1.使用angular自己的事件機制
在controller裡面使用,加入a向b發事件通知:
2.用service模擬回調事件,本質是用service保存了一個全域的回呼函數供controller之間使用
嗯。可以試試事件冒泡和隧道機制。
可以看看這個
直接一點的可以嘗試$broadcast和$on,但是效率會比較差
看樓上寫的不夠純粹(參雜其他考慮),我來補充下純粹版。
提供的 demo
程式碼如下
1).來個事件匯流排,全域對所有的事件進行管理
2).使用 $broadcast 和 $emit