-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AngularJS 中 Controller 之间的通信 #8
Comments
楼主好,按照您说的方法,使用rootScope进行广播,会出现如下错误,是为什么呢? |
@EtachGu 有在 Controller 里面注入 $rootScope 吗? |
有啊注入$rootScope, 但是还是报错! 另外,有个问题想请教一下,如果使用ng-view, 会出现跨Scope的两个Ctrl1与Ctrl2之间的通信问题,Ctrl2中的$rootScope不等于Ctrl1中的$rootScope,这个怎么解决呢? index.html :
sub.html :
JS : var myApp= angular.module('myApp', [
'ngRoute'
]);
myApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/sub', {
templateUrl: 'sub.html'
}).
otherwise({
redirectTo: '/sub'
});
}]);
myApp.controller('Ctrl1',['$scope','$rootScope',function($scope,$rootScope){
$scope.click = function(){
$rootScope.$broadcast('Update', "CCC");
}
}]);
myApp.controller('Ctrl2',['$scope','$rootScope',function($scope,$rootScope){
$scope.content = "AAA";
$rootScope.$on('Update',function(){
$scope.content = c;
});
}]); |
@EtachGu 前面注入$rootScope 还是报错的相关代码你贴出来我看下。 后面那个问题,按照你代码这样写,是没问题的,如果你在 $rootScope.$on 的地方是下面这样写的话: $rootScope.$on('Update',function(e, c){
$scope.content = c;
}); 回调里面,第二个参数是 data |
我刚刚测试了一下,只用angular按照rootScope的方法通信没问题,估计是我用了bootstrap 和 OpenLayer 等之后就出问题了。 |
我知道问题了,是
多写了一个$document,然后对应到了function参数$rootScope了, |
@EtachGu 是的,依赖性跟参数必须一一对应 |
楼主好,请问service,factory和Providers有啥区别?我的数据源是异步获取的,应该用哪种方式? |
@sky-admin 三者的区别你可以看看这篇 AngularJS 中 Provider 的用法及区别,三者都可用于异步获取数据,通常情况下直接用 service 就可以 |
楼主很棒,解决了我的疑惑,感谢 |
很全的总结,多谢lz |
用 Angular 进行开发,基本上都会遇到 Controller 之间通信的问题,本文对此进行一个总结。
在 Angular 中,Controller 之间通信的方式主要有三种:
1)作用域继承。利用子 Controller 控制父 Controller 上的数据。(父 Controller 中的数据要为引用类型,不能是基本类型,原因参见 AngularJS中的作用域 一文)
2)注入服务。把需要共享的数据注册为一个
service
,在需要的 Controller 中注入。3)基于事件。利用 Angular 的事件机制,使用
$on
、$emit
和$boardcast
其中,作用域继承仅限于上下级之间的通信,注入服务和基于事件的机制可以实现任意级别的 Controller 通信。
在 这里 可以查看下面栗子的演示。
作用域继承
原理在 作用域 一文中有讲解,这里直接上栗子。
页面:
控制器:
以上是父 Controller 中的数据是引用类型的情况。如果父 Controller 中的数据是基本类型,可通过
$scope.$parent.data
访问。很显然,这种方式仅适用于父子级间 Controller 的通信。
注入服务
在 Angular 中,服务是一个单例,所以在服务中生成一个对象,该对象就可以利用依赖注入的方式在所有的控制器中共享。
看个栗子,先定义一个
service
:页面:
控制器:
这种方式适用于任何需要通信的 Controller 之间。
基于事件
Angular 为
$scope
提供了冒泡和隧道机制,$broadcast
会把事件广播给所有子 Controller,而$emit
则会将事件冒泡传递给父 Controller,$on
则是 Angular 的事件监听函数,利用这三者,可以实现上下级和同级(需要构造一个共同的父级 Controller)之间的通信。上下级之间
这种情况下比较简单。
如果是子 Controller 往父 Controller 上发送事件(从作用域往上发送事件),使用
scope.$emit
如果是父 Controller 往子 Controller 上发送事件(从作用域往下发送事件),使用
scope.$broadcast
无论是
$emit
还是$broadcast
发送的事件,都用$scope.$on
接收:同级之间
同级之间利用事件通信有两种方法。一种是利用上下级之间事件传播的变形,另一种是借助
$rootScope
。借助父 controller
先看第一种,在子 Controller 中向父 Controller 触发一个事件,然后在父 Controller 中监听事件,再广播给子 Controller ,这样通过事件携带的参数,实现了数据经过父 Controller,在同级 Controller 之间传播。
但是要注意,通过父 Controller 作为中介进行传递的话,子 Controller 触发的事件名和父 Controller 广播用的事件名不能一样,否则会进入死循环。
看代码:
关键部分在控制器:
借助 $rootScope
每个 Angular 应用默认有一个根作用域
$rootScope
, 根作用域位于最顶层,从它往下挂着各级作用域。所以,如果子控制器直接使用
$rootScope
广播和接收事件,那么就可实现同级之间的通信。看栗子:
控制器:
参考
The text was updated successfully, but these errors were encountered: