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 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之间如何正确的通信的更多相关文章
- AngularJS 中 Controller 之间的通信
用 Angular 进行开发,基本上都会遇到 Controller 之间通信的问题,本文对此进行一个总结. 在 Angular 中,Controller 之间通信的方式主要有三种: 1)作用域继承.利 ...
- AngularJS进阶(九)控制器controller之间如何通信
AngularJS控制器controller之间如何通信 注:请点击此处进行充电! angular控制器通信的方式有三种: 1,利用作用域继承的方式.即子控制器继承父控制器中的内容 2,基于事件的方式 ...
- angularJS中directive与controller之间的通信
当我们在angularJS中自定义了directive之后需要和controller进行通讯的时候,是怎么样进行通讯呢? 这里介绍3种angular自定义directive与controller通信的 ...
- AngularJS实战之Controller之间的通信
我们时常会在不同controller之间进行通信,接下来就介绍三种controller之间的通信方式 一.使用$on.$emit和$broadcast进行controller通信 虽然AngularJ ...
- 跟我学AngularJs:Controller数据共享、继承、通信使用具体解释
林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:本文主讲了AngularJs中的Controller中数据共享.继承.通信的具体使用 本 ...
- angularjs中控制器之间的通信----$on、$emit和$broadcast解析
$on.$emit和$broadcast使得event.data在controller之间的传递变的简单. $emit只能向parent controller传递event与data $broadca ...
- angularjs 中使用 service 在controller 之间 share 对象和数据
在做angularjs 的UI 时,我们经常会遇到一个页面之间有几个controller,在controller 之间share 公共的一些数据和方法就变得比较困难,目前推荐的做法是创建一个servi ...
- angular controller之间通信方式
对于日常开发中,难免会有controller之间通信需求.对于controller之间通信有两种方式可以做到. 用 Angular 进行开发,基本上都会遇到 Controller 之间通信的问题,本文 ...
- angular controller 之间的通信方式
AngularJS中的controller是个函数,用来向视图的作用域($scope)添加额外的功能,我们用它来给作用域对象设置初始状态,并添加自定义行为. 当我们在创建新的控制器时,angularJ ...
随机推荐
- [LeetCode] 42. Trapping Rain Water 解题思路
Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...
- Centos6.4 xen编译部署
ruiy亲测成功,现将步骤总结如下,一步步往下将可 原文链接 http://blog.csdn.net/liyakun1992421/article/details/9071061 xen 与 kvm ...
- MediaInfo源代码分析 2:API函数
本文主要分析MediaInfo的API函数.它的API函数位于MediaInfo.h文件中的一个叫做MediaInfo的类中. 该类如下所示,部分重要的方法已经加上了注释: //MediaInfo类 ...
- datasorttable表格
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...
- C# checked关键字当属性
前端extjs 以及 bootstrap-treeview 插件要用到这个属性,加@符号解决
- WPF ArrangeOverride与MeasureOverride
1.MeasureOverride 是FrameworkElement.MeasureOverride 方法 当重写在派生类中,单位是对于子元素所需要布局的大小并确定FrameworkElement ...
- 在地图上添加POI
使用Tangram的Marker, 可以在地图上做各种标记, 效果图: Tangram是通过Marker在地图上添加标记的,Marker分Point, Polyline和Polygon三种, 分别对应 ...
- FontCombobox 和FontSizeCombobox
附件:http://files.cnblogs.com/xe2011/WindowsFormsFontCombox.rar 自定义组件字体组合框 自定义组件字体组合框如何使用 自定义组件字体大小组合框 ...
- 手动安装 mysqldb 与[ pip easy_install]
mysqldb下载: http://sourceforge.net/projects/mysql-python/ https://sourceforge.net/projects/mysql-pyth ...
- WPF组件开发之组件的基类
之前在网上看到很多关于组件开发的资料,但真正可以用到框架内的却很少.今天贴出自己做的组件,并适合大部分框架的代码. 组件开发需要先做出组件的基类,然后由其他的各类组件去继承这个基类,下面是组件基类的代 ...