angular controller之间通信方式
对于日常开发中,难免会有controller之间通信需求。对于controller之间通信有两种方式可以做到。
用 Angular 进行开发,基本上都会遇到 Controller 之间通信的问题,本文对此进行一个总结。
在 Angular 中,Controller 之间通信的方式主要有三种:
1)作用域继承。利用子 Controller 控制父 Controller 上的数据。(父 Controller 中的数据要为引用类型,不能是基本类型,原因参见 AngularJS中的作用域 一文)
2)注入服务。把需要共享的数据注册为一个 service
,在需要的 Controller 中注入。
3)基于事件。利用 Angular 的事件机制,使用 $on
、$emit
和 $boardcast
其中,作用域继承仅限于上下级之间的通信,注入服务和基于事件的机制可以实现任意级别的 Controller 通信。
在 这里 可以查看下面栗子的演示。
作用域继承
原理在 作用域 一文中有讲解,这里直接上栗子。
页面:
<div ng-controller="parentCtrl">
<p>data in parent controller : {{data.name}}</p>
<div ng-controller="childCtrl">
<input type="text" ng-model="data.name">
</div>
</div>
控制器:
angular.module('demo', []) .controller('parentCtrl', ['$scope', function($scope){
$scope.data = {
name: 'htf'
}
}]) .controller('childCtrl', ['$scope', function($scope){ }])
以上是父 Controller 中的数据是引用类型的情况。如果父 Controller 中的数据是基本类型,可通过$scope.$parent.data
访问。
很显然,这种方式仅适用于父子级间 Controller 的通信。
注入服务
在 Angular 中,服务是一个单例,所以在服务中生成一个对象,该对象就可以利用依赖注入的方式在所有的控制器中共享。
看个栗子,先定义一个 service
:
angular.module('demo')
.factory('Data', function(){
return {
name: 'htf'
};
})
页面:
<div ng-controller="childCtrl1">
<h3>data in child controller 1 : {{data.name}}</h3>
<input class="form-control" type="text" ng-model="data.name">
</div>
<div ng-controller="childCtrl2">
<h3>data in child controller 2 : {{data.name}}</h3>
<input class="form-control" type="text" ng-model="data.name">
</div>
控制器:
.controller('childCtrl1', ['$scope', 'Data', function($scope, Data){
$scope.data = Data;
}]) .controller('childCtrl2', ['$scope', 'Data', function($scope, Data){
$scope.data = Data;
}])
这种方式适用于任何需要通信的 Controller 之间。
基于事件
Angular 为 $scope
提供了冒泡和隧道机制,$broadcast
会把事件广播给所有子 Controller,而 $emit
则会将事件冒泡传递给父 Controller,$on
则是 Angular 的事件监听函数,利用这三者,可以实现上下级和同级(需要构造一个共同的父级 Controller)之间的通信。
上下级之间
这种情况下比较简单。
如果是子 Controller 往父 Controller 上发送事件(从作用域往上发送事件),使用 scope.$emit
$scope.$emit("someEvent", {});
如果是父 Controller 往子 Controller 上发送事件(从作用域往下发送事件),使用 scope.$broadcast
$scope.$broadcast("someEvent", {});
无论是 $emit
还是 $broadcast
发送的事件,都用 $scope.$on
接收:
$scope.$on("someEvent", function(event, data) {
// 这里取到发送过来的数据 data
});
同级之间
同级之间利用事件通信有两种方法。一种是利用上下级之间事件传播的变形,另一种是借助 $rootScope
。
借助父 controller
先看第一种,在子 Controller 中向父 Controller 触发一个事件,然后在父 Controller 中监听事件,再广播给子 Controller ,这样通过事件携带的参数,实现了数据经过父 Controller,在同级 Controller 之间传播。
但是要注意,通过父 Controller 作为中介进行传递的话,子 Controller 触发的事件名和父 Controller 广播用的事件名不能一样,否则会进入死循环。
看代码:
<div ng-controller="outerCtrl">
<h3>data in outer controller: {{name}}</h3>
<div ng-controller="innerCtrl1">
<input class="form-control" type="text" ng-model="name" ng-change="change()">
</div>
<div ng-controller="innerCtrl2">
<input class="form-control" type="text" ng-model="name" ng-change="change()">
</div>
</div>
关键部分在控制器:
.controller('outerCtrl', ['$scope', function($scope){
$scope.name = 'htf';
$scope.$on('dataChanged', function(event, data){
$scope.name = data;
// 2. 父 Ctrl 监听到 dataChanged 时间后,触发 changeData 事件
$scope.$broadcast('changeData', data);
})
}]) .controller('innerCtrl1', ['$scope', function($scope){
$scope.change = function(){
// 1. 子 Ctrl1 中数据改变之后触发 dataChanged 事件
$scope.$emit('dataChanged', $scope.name);
}
$scope.$on('changeData', function(event, data){
$scope.name = data;
})
}]) .controller('innerCtrl2', ['$scope', function($scope){
$scope.change = function(){
$scope.$emit('dataChanged', $scope.name);
}
// 3. 监听到 changeData 事件后,改变子 Ctrl2 中 数据
$scope.$on('changeData', function(event, data){
$scope.name = data;
})
}])
借助 $rootScope
每个 Angular 应用默认有一个根作用域 $rootScope
, 根作用域位于最顶层,从它往下挂着各级作用域。
所以,如果子控制器直接使用 $rootScope
广播和接收事件,那么就可实现同级之间的通信。
看栗子:
<div ng-controller="innerCtrlA">
<input class="form-control" type="text" ng-model="name" ng-change="change()">
</div>
<div ng-controller="innerCtrlB">
<input class="form-control" type="text" ng-model="name" ng-change="change()">
</div>
控制器:
.controller('innerCtrlA', ['$scope', '$rootScope', function($scope, $rootScope){
$scope.change = function(){
// 广播事件
$rootScope.$broadcast('nameChanged', $scope.name);
}
$rootScope.$on('nameChanged', function(event, data){
$scope.name = data;
})
}]) .controller('innerCtrlB', ['$scope', '$rootScope', function($scope, $rootScope){
$scope.change = function(){
$rootScope.$broadcast('nameChanged', $scope.name);
}
// 监听事件
$rootScope.$on('nameChanged', function(event, data){
$scope.name = data;
})
}])
参考
- 作用域与事件
- Angularjs Controller 间通信机制
- Communicating Between Controllers In Angular
- AngularJS控制器controller如何通信?
- controller 间共享数据
angular controller之间通信方式的更多相关文章
- angular controller 之间的通信方式
AngularJS中的controller是个函数,用来向视图的作用域($scope)添加额外的功能,我们用它来给作用域对象设置初始状态,并添加自定义行为. 当我们在创建新的控制器时,angularJ ...
- AngularJS进阶(九)控制器controller之间如何通信
AngularJS控制器controller之间如何通信 注:请点击此处进行充电! angular控制器通信的方式有三种: 1,利用作用域继承的方式.即子控制器继承父控制器中的内容 2,基于事件的方式 ...
- AngularJS实战之Controller之间的通信
我们时常会在不同controller之间进行通信,接下来就介绍三种controller之间的通信方式 一.使用$on.$emit和$broadcast进行controller通信 虽然AngularJ ...
- angular view之间的数据传递
之前写过一篇backbone view之间的传递,由于现在在用angular搞开发,现在也来总结一下.在angular 传递数据通俗的讲叫做 广播 ,在一些文章中,也叫做事件的发布与订阅,在angul ...
- angularJS中directive与controller之间的通信
当我们在angularJS中自定义了directive之后需要和controller进行通讯的时候,是怎么样进行通讯呢? 这里介绍3种angular自定义directive与controller通信的 ...
- Angular 1与 Angular 2之间的一些差别
现在在用ng1.5.8做一个项目,ng的优点和特性我就不用多说了,ng1在陆续更新到1.5/1.6后就没再推出新版本了,ng2已经面世测试很久了,如同很多系统和框架一样,每个大的版本更新都会有新特性加 ...
- 通过$broadcast或$emit在子级和父级controller之间进行值传递
通过$broadcast或$emit在controller之间进行值传递,不过这些controller必须是子级或者父级关系, $emit只能向父级parent controller传递事件event ...
- AngularJS 中 Controller 之间的通信
用 Angular 进行开发,基本上都会遇到 Controller 之间通信的问题,本文对此进行一个总结. 在 Angular 中,Controller 之间通信的方式主要有三种: 1)作用域继承.利 ...
- angularjs 中使用 service 在controller 之间 share 对象和数据
在做angularjs 的UI 时,我们经常会遇到一个页面之间有几个controller,在controller 之间share 公共的一些数据和方法就变得比较困难,目前推荐的做法是创建一个servi ...
随机推荐
- CSS---------------之文本颜色
CSS2支持如下名字的颜色 注意点: 你的浏览器有可能支持更多名字,但是在实际用的过程中尽量少使用名字的,因为各个浏览器对颜色的会存在差异:查看颜色可以参考 对于更多地颜色,你可以使用代表红,绿,蓝三 ...
- Android--------Java接口回调
>###回调说明 回调说明: 1.class A,class B 2.class A 实现接口callback 3.class B拥有一个参数为c ...
- nginx 搭建rtmp流媒体所用资源
Linux: 1.nginx安装包,自行下载. 2.nginx_mod_h264_streaming-2.2.7下载 3.nginx-rtmp-module-master下载 Windows: ngi ...
- C++中const
[const] 0.普通const对象定义在栈空间中 { ; ; cout << &a << ' ' << &b; } Result: 0x22ab ...
- 【转载】 Searching过程粗略梳理
转载自:http://www.cnblogs.com/huangfox/archive/2012/02/09/2344686.html solr-searching过程分析(一) --searchin ...
- 10 个十分难得的 javascript 开发经验
Javascript 的很多扩展的特性是的它变得更加的犀利, 同时也给予程序员机会创建更漂亮并且更让用户喜欢的网站. 尽管很多的开发人员都乐于颂扬 javascript,但是仍旧有人看到它的阴暗面. ...
- Primo Ramdisk配置教程
首先感谢xiaohu在太平洋电脑网上发表的“将内存当硬盘用!Primo Ramdisk图文教程”,本文主要是将其图文整理了一下,以方便以后使用. 原文地址:http://fashion.pconlin ...
- LeetCode_Integer to Roman
Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 t ...
- USB-CSW之旅
前面总结了usb mass storage的枚举过程,如果所有枚举正常,那么会进入bulkonly协议定义的数据交流,在这个数据包里面还包含了SCSI的协议. Bulkonly协议usbmassbul ...
- linux命令行常用快捷键
方向 <-前 后 ->删除ctrl + d 删除光标所在位置上的字符相当于VIM里x或者dlctrl + h 删除光标所在 ...