`

angularJS的controller之间如何正确的通信

阅读更多
AngularJS中的controller是个函数,用来向视图的作用域($scope)添加额外的功能,我们用它来给作用域对象设置初始状态,并添加自定义行为。

当我们在创建新的控制器时,angularJS会帮我们生成并传递一个新的$scope对象给这个controller,在angularJS应用的中的任何一个部分,都有父级作用域的存在,顶级就是ng-app所在的层级,它的父级作用域就是$rootScope。

每个$scope的$root指向$rootScope, $cope.$parent指向父级作用域。

cotroller之间的通信本质上是当前的controller所在的$scope如何跟其他controller上的$scope进行通信。

通常有3中解决方式:

利用作用域继承的原理,子控制器访问父级控制器中的内容。
使用angularJS中的事件,也就是使用$on,$emit,$broadcast进行消息传递
使用angularJS中的服务
第一种方式

即作用域嵌套作用域,有一定的使用限制,需要作用域嵌套起来,在实际开发中这种场景相对比较少,但也不是没有,这种方式更简单直接。

angularJS中默认情况下,当前作用域中无法找到某个属性时,就会在父级作用域中进行查找,若找不到直至查找到$rootScope。 如果在$rootScope中也无法找到程序依旧运行,但视图不会更新。

示例

JavaScript

//Javascript

    app.controller('ParentController', function($scope) {

        $scope.person = {greeted: false};

    });

    app.controller('ChildController', function($scope) {

        $scope.sayHello = function() {

             $scope.person.name = 'Ari Lerner';

        };

    });

    //HTML

     <div ng-controller="ParentController">

       <div ng-controller="ChildController">

         <a ng-click="sayHello()">Say hello</a>

       </div>

       {{ person }}

     </div>

    //result

    {"greeted":true, "name": "Ari Lerner"}
第二种方式

因为作用域是有层次的,所以可以利用作用域链传递事件。

传递事件有2种方式: * $broadcast: 触发的事件要通知整个事件系统(允许任意作用域处理这个事件)就要向下传播。 * $emit: 如果要提醒一个全局模块,需要通知更高层次的作用域时(例如$rootscope)需要把事件向上传递。

作用域上使用$on进行事件监听。

示例

JavaScript

app.controller('ParentController', function($scope) {
        $scope.$on('$fromSubControllerClick', function(e,data){
            console.log(data); // hello
        });
    });

    app.controller('ChildController', function($scope) {
        $scope.sayHello = function() {
            $scope.$emit('$fromSubControllerClick','hello');
        };
    });

    //HTML
     <div ng-controller="ParentController">
       <div ng-controller="ChildController">
         <a ng-click="sayHello()">Say hello</a>
       </div>
     </div>
在这里想要说的另外一个问题就是事件传播的性能问题,$broadcast+$on的方式回通知所有的子作用域,这里就会有性能问题,所以推荐使用$emit+$on的方式,为了进一步提升性能,定义的事件处理函数要在作用域销毁时一起释放掉。

使用$emit+$on的方式需要我们将事件监听绑定在$rootScope上,例如:

JavaScript

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);
        }
    ]);
但是这种方式有点繁琐,定义多个事件处理函数时整个人都不好了,所以我们来改进一下

利用装饰器来定义一个新的事件绑定函数:

JavaScript

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;
        }]);
    }]);
那么我们在控制器中定义事件处理函数时:

JavaScript

angular
    .module('MyApp')
    .controller('MyController', ['$scope', function MyController($scope) {
            $scope.$onRootScope('someComponent.someCrazyEvent', function(){
                console.log('foo');
            });
        }
    ]);
个人强烈推荐此种做法

第三种方式

利用angularJS中service单例模式的特性,服务(service)提供了一种能在应用的整个生命周期内保持数据的方式,能够在控制器之间进行通信,且能保证数据的一致性。

一般我们都会封装server来为应用提供访问数据的接口,或者跟远程进行数据交互。

示例

JavaScript

var myApp = angular.module("myApp", []);
myApp.factory('Data', function() {
  return {
    name: "Ting"
  }
});

myApp.controller('FirstCtrl', function($scope, Data) {
  $scope.data = Data;
  $scope.setName = function() {
    Data.name = "Jack";
  }
});

myApp.controller('SecondCtrl', function($scope, Data) {
  $scope.data = Data;
  $scope.setName = function() {
    Data.name = "Moby";
  }
});
分享到:
评论

相关推荐

    AngularJS控制器controller正确的通信的方法

    在AngularJS中,正确地实现控制器之间的通信是构建复杂应用的关键。以下将详细介绍三种基本的通信方法: 1. 作用域继承的原理 在AngularJS中,作用域($scope)是基于原型继承的机制工作的。这意味着子控制器可以...

    AngularJS入门教程中SQL实例详解

    在AngularJS中,SQL(Structured Query Language)的集成主要用于与后端数据库进行交互,以便获取、更新、删除或插入数据。...了解如何正确地集成和使用这些工具对于任何AngularJS开发者来说都是至关重要的。

    angularJS权威学习指南手册

    AngularJS通过MVC(Model-View-Controller)架构模式提供了一个全面的解决方案,它将数据绑定和依赖注入等特性融入到HTML中,使得开发者可以专注于业务逻辑,而无需过多关注DOM操作。这个框架的主要目标是提高开发...

    AngularJS实现地区选择

    - 指令可能包含一个控制器(Controller),用于处理与地区选择相关的逻辑,如初始化数据、处理用户交互等。 - 使用`template`或` templateUrl `属性定义指令的视图模板,模板中可以包含HTML元素,如`&lt;select&gt;`、`...

    AngularJs 后台登录界面

    **AngularJs 后台登录界面开发详解** AngularJs,作为一款强大的前端JavaScript框架,由Google维护,主要用于构建单页应用程序(SPA)。它以其双向数据绑定、模块化、依赖注入等特性,极大地提高了Web开发的效率。...

    AngularJS全局scope与Isolate scope通信用法示例

    AngularJS是一种前端开发框架,它使用了MVC(Model-View-Controller)设计模式,以及MVVM(Model-View-ViewModel)模式。它的核心是利用了JavaScript中的数据绑定功能,以此来简化动态HTML的应用开发。在AngularJS中...

    07angularjs4.x请求数据(上).zip

    最后,本教程可能还会涉及到AngularJS的模块(Module)、控制器(Controller)和路由(Routing)等基础知识,这些都是构建复杂单页面应用(SPA)的关键组成部分。通过学习如何在控制器中发起请求,以及如何在视图中...

    简述AngularJS相关的一些编程思想

    AngularJS通过双向数据绑定简化了前端开发,使得视图和模型之间的同步变得自动化,极大地提高了开发效率。在标题和描述中提到的项目,如创建一个类似Photoshop的浏览器编辑器,就充分体现了AngularJS的强大之处。 ...

    基于angularJs和Bootstrap的简易计算器

    4. **服务**:AngularJS的服务提供了一种方式来封装可重用的功能,如$http服务用于与服务器进行HTTP通信,$scope服务作为控制器和视图之间的数据桥梁。 5. **模块**:AngularJS应用通常由一个或多个模块组成,模块...

    AngularJS Handbook_ Easy Web App Development

    - **$apply()**: 触发一次消化循环,并确保在非AngularJS上下文中(如定时器)所做的更改也能被正确检测到。 **示例:** ```javascript $scope.$watch('model', function(newVal, oldVal) { if (newVal !== ...

    AngularJS Directives

    AngularJS Directives可以通过作用域进行通信,也可以使用控制器或服务来进行更复杂的数据共享。 #### 四、AngularJS Directives的高级用法 除了基本的自定义指令外,还有更多高级特性可用于构建复杂的应用程序。 ...

    用AngularJS做的静态的增删改查

    10. **最佳实践**:在实际项目中,还需要遵循AngularJS的最佳实践,如使用controllerAs语法、避免在控制器中直接进行DOM操作、以及充分利用指令来封装复杂UI逻辑等。 通过这个"用AngularJS做的静态的增删改查"项目...

    使用AngularJs ASP.NET MVC Web API EF构建一个多层SPA的例子

    3. **数据服务**:AngularJS应用通常会有一个数据服务模块,封装了与Web API的通信。这个服务使用$http或$httpProvider来发送GET、POST、PUT和DELETE请求。 4. **模型和实体**:在ASP.NET MVC和Entity Framework中...

    angular js最新版

    数据绑定允许视图和模型之间的双向通信,使得UI的更新与数据模型的变化同步。依赖注入则简化了代码间的耦合,通过提供一种方式来声明所需的对象,而无需知道它们如何被创建或在哪里被定义。 1.3.0.14版本可能包含了...

    Angularjs(增删改+分页+弹框+Sql数据库)

    6. **最简单的Mvc框架**:尽管AngularJS本身不是典型的MVC(Model-View-Controller)框架,但其设计理念与MVC相似。在示例中,模型可能是存储在服务中的数据,视图是用户界面,而控制器则负责协调两者之间的交互。 ...

    ionic按需加载controller解决方案

    使用服务(Services)来存储和共享数据,而不是依赖于Controller间的直接通信;合理组织和拆分模块,减少单个文件的大小。 6. **性能监控**: 实施按需加载后,应持续监控应用的性能,如加载时间、内存使用情况等...

    angularjs1.X 重构controller 的方法小结

    父子控制器之间的通信可以通过消息机制进行,如使用$broadcast、$emit、$on事件进行父子或兄弟控制器之间的通信。 二、模块划分 通过组合视图来实现模块划分,使得每个子视图可以共享同一个路由地址,但分管不同的...

Global site tag (gtag.js) - Google Analytics