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

     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进行事件监听。

示例

 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上,例如:

 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);
}
]);

但是这种方式有点繁琐,定义多个事件处理函数时整个人都不好了,所以我们来改进一下

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

 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');
});
}
]);

个人强烈推荐此种做法

第三种方式

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

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

示例

 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之间如何正确的通信的更多相关文章

  1. AngularJS 中 Controller 之间的通信

    用 Angular 进行开发,基本上都会遇到 Controller 之间通信的问题,本文对此进行一个总结. 在 Angular 中,Controller 之间通信的方式主要有三种: 1)作用域继承.利 ...

  2. AngularJS进阶(九)控制器controller之间如何通信

    AngularJS控制器controller之间如何通信 注:请点击此处进行充电! angular控制器通信的方式有三种: 1,利用作用域继承的方式.即子控制器继承父控制器中的内容 2,基于事件的方式 ...

  3. angularJS中directive与controller之间的通信

    当我们在angularJS中自定义了directive之后需要和controller进行通讯的时候,是怎么样进行通讯呢? 这里介绍3种angular自定义directive与controller通信的 ...

  4. AngularJS实战之Controller之间的通信

    我们时常会在不同controller之间进行通信,接下来就介绍三种controller之间的通信方式 一.使用$on.$emit和$broadcast进行controller通信 虽然AngularJ ...

  5. 跟我学AngularJs:Controller数据共享、继承、通信使用具体解释

    林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:本文主讲了AngularJs中的Controller中数据共享.继承.通信的具体使用 本 ...

  6. angularjs中控制器之间的通信----$on、$emit和$broadcast解析

    $on.$emit和$broadcast使得event.data在controller之间的传递变的简单. $emit只能向parent controller传递event与data $broadca ...

  7. angularjs 中使用 service 在controller 之间 share 对象和数据

    在做angularjs 的UI 时,我们经常会遇到一个页面之间有几个controller,在controller 之间share 公共的一些数据和方法就变得比较困难,目前推荐的做法是创建一个servi ...

  8. angular controller之间通信方式

    对于日常开发中,难免会有controller之间通信需求.对于controller之间通信有两种方式可以做到. 用 Angular 进行开发,基本上都会遇到 Controller 之间通信的问题,本文 ...

  9. angular controller 之间的通信方式

    AngularJS中的controller是个函数,用来向视图的作用域($scope)添加额外的功能,我们用它来给作用域对象设置初始状态,并添加自定义行为. 当我们在创建新的控制器时,angularJ ...

随机推荐

  1. cygwin下安装hadoop0.20

    安装时选择软件包: editor-两个VIM.base-SED.Net-OPENSSH.OPENSSL.libs-libintl3和libintl8 环境变量: path=%JAVA_HOME%\bi ...

  2. CMDB机柜平台结合zabbix告警展示

    前段时间看了刘天斯老师的机柜展示平台,非常绚丽,而且有大屏显示的话也是能够体现运维价值的.刚好最近自己也在协助朋友做一个开源的CMDB平台,这里就说下我们CMDB平台的一些数据: 开源项目地址:Git ...

  3. kafka rebalance 部分分区没有owner

    转发请注明原创地址http://www.cnblogs.com/dongxiao-yang/p/6234673.html 最近业务同学反馈kafka上线的时候某个topic的部分分区一直没有owner ...

  4. Hibernate查询方法总结

    1. HQL查询 HQL是Hiberante官方推荐的Hibernate检索方式,它使用类似SQL的查询语言,以面向对象的方式从数据库中查询.可以使用HQL查询具有继承.多态和关 联关系的数据.在检索 ...

  5. C# 可访问一致性不一致

    出现原因,其中一个是返回参数的访问级别小于函数的访问级别, 也就是说当定义一个返回参数的方法的时候,如果返回参数的访问级别低于方法的访问级别就会出现这样的错误,这个是可以理解的,如果返回的参数不能被访 ...

  6. leetcode 题解 || Swap Nodes in Pairs 问题

    problem: Given a linked list, swap every two adjacent nodes and return its head. For example, Given ...

  7. CSS 边框 阴影 效果

    CSS 边框 阴影 效果 以下将css实现阴影效果,以便须要朋友们,直接上代码 #shadow1{ width: 200px; height: 100px; color: white; backgro ...

  8. spring security3.2配置---权限管理

    之前已经在我的博客中发过security的执行流程图了,大家能够先去看看那个图再看这篇.今天我主要在这里贴出了security配置中的几个重要的类和两个xml配置文件,基本上控制权限的就是这几个文件了 ...

  9. [Angular 2] DI in Angular 2 - 1

    Orgial aritial --> Link The problem with Angular 1 DI: Angular 2 DI: Solve the singletons problem ...

  10. 通过源码看android系列之AsyncTask

    整天用AsyncTask,但它的内部原理一直没有特意去研究,今天趁着有时间,码下它的原理. 具体用法就不再说明,相信大家已经用得很熟练了,我们今天就从它怎么运行开始说.先新建好我们的AsyncTask ...