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 ...
随机推荐
- Oracle静默安装-简单记录
一.与图形界面安装一样,检查如下条件:新建用户.组创建安装目录配置环境变量检查安装依赖包修改内核参数……前面这些操作都属于常规操作,不管是图形还是静默都需要处理. 二./home/oracle/dat ...
- Query获取值常用
Query获取Select选择的Text和Value:语法解释:1. $("#select_id").change(function(){//code...}); //为Sel ...
- ado.net数据库操作(2)
5.1使用SQLDataReader进行数据库查询 <%@ Import Namespace="System.Data" %> <%@ Import NameSp ...
- Thread was being aborted.你遇到了吗?
这个Exception目前了解到的有两个原因造成: 1.Reponse.Write的问题(目前网上找到的信息十有八九都讲的是这个问题) 2.Web.Config中设定的exec ...
- 1203.2——条件语句 之 switch语句
用 if else 语句在处理多分支的时候,分支太多就会显得不方便,且容易出现 if 和 else配对出现错误的情况.例如,输入一个整数,输出该整数对应的星期几的英文表示: #include < ...
- UIScrollView的基本使用和一些常用代理方法
- (void)viewDidLoad { [super viewDidLoad]; scrollView = [[UIScrollView alloc] initWithFrame:CGRectMa ...
- Js中单引号和双引号的区别
<html> <body> <input value="外双引号内双引号-错误" type="button" onclick=&q ...
- C++之------虚函数
今天又是周日,公司工业区这里九月份每个周日都会停电一天.停电停网,是没法活的.我们直接去老大家. 老大当爸爸了,回家一段时间了.听说孩子出生就不乖,很折腾他爸妈,这小家伙新生命二代.也愿小家伙早日康复 ...
- 推荐的 CSS 书写顺序
//显示属性 display list-style position float clear //自身属性 width height margin padding border background ...
- build.gradle中引入jar
只需在 dependencies{}中添加: compile fileTree(include: ['*.jar'], dir: 'libs')