suchen

Heim  >  Fragen und Antworten  >  Hauptteil

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

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

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

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

迷茫迷茫2744 Tage vor867

Antworte allen(5)Ich werde antworten

  • PHP中文网

    PHP中文网2017-05-15 16:58:29

    我这边尝试过两种:
    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);
                        };
                    }                    
                }
            }
        }
    })();

    Antwort
    0
  • 过去多啦不再A梦

    过去多啦不再A梦2017-05-15 16:58:29

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

    Antwort
    0
  • 给我你的怀抱

    给我你的怀抱2017-05-15 16:58:29

    可以看看这个

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

    Antwort
    0
  • 滿天的星座

    滿天的星座2017-05-15 16:58:29

    看楼上写的不够纯粹(参杂其他考虑),我来补充下纯粹版。
    提供的 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>

    Antwort
    0
  • 黄舟

    黄舟2017-05-15 16:58:29

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

    Antwort
    0
  • StornierenAntwort