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 ...
随机推荐
- C#基础学习心得(一)
类的成员 数据成员:字段,常量(const) 函数成员:方法,属性,索引器,构造函数,析构函数,事件 类的声明 实例成员:对象相关性,不同于同一类的其他实例 静态成员:常量,static修饰的字段,方 ...
- Javascript进阶篇——浏览器对象—History对象
History 对象history对象记录了用户曾经浏览过的页面(URL),并可以实现浏览器前进与后退相似导航的功能.窗口被打开的那一刻开始记录,每个浏览器窗口.每个标签页乃至每个框架,都有自己的hi ...
- SQLserver 连接+开窗函数+视图+事务
今天学习SQLserver 连接以及开窗函数..加油! 1.复习:查询(检索)->筛选列->筛选行:distinct top where 运算符与关键字:比较运算符,逻辑运算符,betwe ...
- Repeater里面加上if判断
//创建时绑定 protected void ItemCreated(object sender, RepeaterItemEventArgs e) { if (e.Item.DataItem != ...
- (转) 新手入门:C/C++中的结构体
本文转载于 http://pcedu.pconline.com.cn/empolder/gj/c/0503/567930_all.html#content_page_1 所有程序经过本人验证,部分程序 ...
- 第一章 Qt入门
1.1Qt 窗口部件 widget,用户界面的一个可视化元素,任意窗口部件都可以作为窗口.可以通过简单的HTML修改丰富样式 1.2建立连接 Qt的窗口部件通过发射信号(signal)来表明一个用户动 ...
- 两个string数组对应比较
最近做的array string类型对比.这个可能比较复杂,用的是linq 是请教别人的,我在这里记录一下 jquery 方法里面的数组 function arrtxt() { var arrt= [ ...
- 关于安卓的log学习
什么时候会产生log文件? 1. 程序异常退出 Uncaused Exception. 2. 程序强制关闭 Force Closed(FC). 3. 程序无响应 Application No Resp ...
- sql中插入多条记录-微软批处理
这是使用批处理的一个例子: System.IO.StreamWriter messagelog = null; string messageString = ""; SqlConn ...
- [TYVJ] P1049 最长不下降子序列
最长不下降子序列 描述 Description 求最长不下降子序列的长度 输入格式 InputFormat 第一行为n,表示n个数第二行n个数 输出格式 OutputFormat 最长不下降子 ...