当前位置: 首页 > 知识库问答 >
问题:

在AngularJS中控制器之间的正确通信方式是什么?

步博涉
2023-03-14

控制人员之间的正确通信方式是什么?

我目前正在使用一个可怕的软糖,涉及窗口:

function StockSubgroupCtrl($scope, $http) {
    $scope.subgroups = [];
    $scope.handleSubgroupsLoaded = function(data, status) {
        $scope.subgroups = data;
    }
    $scope.fetch = function(prod_grp) {
        $http.get('/api/stock/groups/' + prod_grp + '/subgroups/').success($scope.handleSubgroupsLoaded);
    }
    window.fetchStockSubgroups = $scope.fetch;
}

function StockGroupCtrl($scope, $http) {
    ...
    $scope.select = function(prod_grp) {
        $scope.selectedGroup = prod_grp;
        window.fetchStockSubgroups(prod_grp);
    }
}

共有1个答案

龙星辰
2023-03-14

所以,现在你可以:

  • $rootscope
  • 中使用 $broadcast
  • 使用$on从需要了解事件的本地$scope监听

以下原始答案

然而,在控制器内部使用它时有一个问题。如果从控制器中直接绑定到$rootscope.$on(),则必须在本地$scope被破坏时自行清理绑定。这是因为控制器(与服务相反)可以在应用程序的生存期内被多次实例化,这将导致绑定汇总,最终在所有地方造成内存泄漏:)

要取消注册,只需监听$scope$destroy事件,然后调用$rootscope.$on返回的函数。

angular
    .module('MyApp')
    .controller('MyController', ['$scope', '$rootScope', function MyController($scope, $rootScope) {

            var unbind = $rootScope.$on('someComponent.someCrazyEvent', function(){
                console.log('foo');
            });

            $scope.$on('$destroy', unbind);
        }
    ]);

我想说,这并不是一个真正的角度特定的事情,因为它也适用于其他EventBus实现,您必须清理资源。

monkey修补$rootscope以提供这样的$onrootscope方法的最干净的方法是通过一个decorator(运行块可能也能很好地完成它,但是pssst,不要告诉任何人)

为了确保在对$scope进行枚举时$onrootscope属性不会意外显示,我们使用object.defineproperty()并将enumerable设置为false。请记住,您可能需要一个ES5垫片。

angular
    .module('MyApp')
    .config(['$provide', function($provide){
        $provide.decorator('$rootScope', ['$delegate', function($delegate){

            Object.defineProperty($delegate.constructor.prototype, '$onRootScope', {
                value: function(name, listener){
                    var unsubscribe = $delegate.$on(name, listener);
                    this.$on('$destroy', unsubscribe);

                    return unsubscribe;
                },
                enumerable: false
            });


            return $delegate;
        }]);
    }]);

有了这种方法,上面的控制器代码可以简化为:

angular
    .module('MyApp')
    .controller('MyController', ['$scope', function MyController($scope) {

            $scope.$onRootScope('someComponent.someCrazyEvent', function(){
                console.log('foo');
            });
        }
    ]);

因此,作为所有这些的最终结果,我强烈建议您使用$rootscope.$emit+$scope.$onrootscope

顺便说一句,我正试图说服angular团队在angular核心内解决这个问题。这里有一个讨论:https://github.com/angular/angular.js/issues/4574

下面是一个jsperf,它显示了在一个只有100个$scope的良好场景中,$broadcast会给表带来多少perf影响。

 类似资料:
  • 本文向大家介绍AngularJS控制器之间的通信方式详解,包括了AngularJS控制器之间的通信方式详解的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了AngularJS控制器之间的通信方式。分享给大家供大家参考,具体如下: 一、利用作用域的继承方式 由于作用域的继承是基于js的原型继承方式,所以这里分为两种情况,当作用域上面的值为基本类型的时候,修改父作用域上面的值会影响到子作用域,反

  • 本文向大家介绍AngularJS控制器controller正确的通信的方法,包括了AngularJS控制器controller正确的通信的方法的使用技巧和注意事项,需要的朋友参考一下 AngularJS是一款非常强大的前端MVC框架,AngularJS中的controller是个函数,用来向视图的作用域($scope)添加额外的功能,我们用它来给作用域对象设置初始状态,并添加自定义行为。 当我们在

  • 本文向大家介绍Angularjs实现控制器之间通信方式实例总结,包括了Angularjs实现控制器之间通信方式实例总结的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Angularjs实现控制器之间通信方式。分享给大家供大家参考,具体如下: 利用angularjs开发项目中,控制器之间的通信,比如参数的传递,数据的传递,都是比较常见的。控制器之间的通信,显得尤为重要。常见的方式有如下两种:

  • 本文向大家介绍AngularJS开发教程之控制器之间的通信方法分析,包括了AngularJS开发教程之控制器之间的通信方法分析的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了AngularJS开发教程之控制器之间的通信方法。分享给大家供大家参考,具体如下: 一、指令与控制器之间通信,无非是以下几种方法: 基于scope继承的方式 基于event传播的方式 service的方式(单例模式)

  • 我有控制器A,它将一些数据发送给共享服务,控制器B应该读取这些数据。问题是控制器B与控制器a在不同的页面(在同一网站上),即我做SMTH。在控制器A上,单击按钮(向服务发送数据)并打开另一个页面,其中是控制器B,它应该从服务读取数据。但是什么也没有发生,所以我的问题是,不同页面上的控制器能这样通信吗? 以下是我如何尝试去做,但没有运气: 服务: 控制器A相关部分: 控制器B相关部分: 甚至也不会被

  • 问题内容: 我正在阅读有关Angular验证的文章,并认为在我自己的项目中使用它会很好。它运行得非常好,我想在成功验证表单后在其他控制器中扩展它的访问方法。我尝试了各种方法来执行此操作,但似乎看不到$ scope对象中的方法。 我希望有人能告诉我我想念的东西才能完成这项工作。我叉了个笨蛋。 问题答案: 正确的方法是使用角度服务。例如: 这样,您可以在注入到的任何控制器中访问内部功能: 看到这个演示