AngularJS controller控制器间的通信

一. 作用域继承实现通信

先看一组代码:

<!DOCTYPE HTML>
<html>
    <head>
		<meta charset="utf-8"/>
		<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
		<meta name="viewport" content="initial-scale=1, maximum-scale=3, minimum-scale=1, user-scalable=no"/>
		<title>标题</title>
    </head>
    <body ng-app="test">
		<div ng-controller="parentCtrl">
			parent: <input ng-model="user.content" />
			<div ng-controller="childCtrl">
				child: <input ng-model="user.content" />
				<button ng-click="initClick()">init</button>
			</div>
		</div>
		
		<script src="bower_components/angular/angular.min.js"></script>
		<script>
			angular.module('test',[])
			.controller('parentCtrl', parentCtrl)
			.controller('childCtrl', childCtrl);

			function parentCtrl($scope){
				$scope.user = {content: 'content'};
				$scope.init = function(){
					$scope.user.content = 'init';
				}
			}
			function childCtrl($scope){
				$scope.initClick = function(){
					$scope.init();
				}
			}
		</script>
    </body>
</html>

在这里插入图片描述
结论:改变父作用域下的模型,子作用域下的模型也会改变;点击子作用域下按钮,同样可以触发父作用域下controller定义的方法;
前提:子作用域下controller不能定义同样的方法或模型,否则会覆盖上层作用域;
缺点:不能用在复杂情况;不易维护;

作用域详解:https://blog.csdn.net/lizhongyang21/article/details/103120292

二. $rootScope

$rootScope 是特殊的作用域继承实现通信的方式;

<!DOCTYPE HTML>
<html>
    <head>
		<meta charset="utf-8"/>
		<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
		<meta name="viewport" content="initial-scale=1, maximum-scale=3, minimum-scale=1, user-scalable=no"/>
		<title>标题</title>
    </head>
    <body ng-app="test">
		<div ng-controller="parentCtrl">
			parent: <span ng-bind="user.name"></span>
			<div ng-controller="childCtrl">
				child: <span ng-bind="user.name"></span><br>
				<button ng-click="initClick()">init</button>
			</div>
		</div>
		
		<script src="bower_components/angular/angular.min.js"></script>
		<script>
			angular.module('test',[])
			.controller('parentCtrl', parentCtrl)
			.controller('childCtrl', childCtrl);

			function parentCtrl($scope, $rootScope){
				$rootScope.user = {
					name: 'parent'
				};
			}
			function childCtrl($scope, $rootScope){
				$scope.initClick = function(){
					$rootScope.user = {
						name: 'child'
					};
				}
			}
		</script>
    </body>
</html>

适用:不经常改变,但是许多页面需要使用的数据。如:用户的信息,用户的权限等;

三. $emit, $on, $broadcast
<!DOCTYPE HTML>
<html>
    <head>
		<meta charset="utf-8"/>
		<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
		<meta name="viewport" content="initial-scale=1, maximum-scale=3, minimum-scale=1, user-scalable=no"/>
		<title>标题</title>
    </head>
    <body ng-app="test">
		<div ng-controller="parentCtrl">
			<div ng-controller="childCtrl1">
				child1: <span ng-bind="name"></span><br>
			</div>
			<div ng-controller="childCtrl2">
				child2: <span ng-bind="name"></span><br>
				<button ng-click="initClick()">child2Click</button>
			</div>
		</div>
		
		<script src="bower_components/angular/angular.min.js"></script>
		<script>
			angular.module('test',[])
			.controller('parentCtrl', parentCtrl)
			.controller('childCtrl1', childCtrl1)
			.controller('childCtrl2', childCtrl2);

			function parentCtrl($scope, $rootScope){
				$scope.name = 'parent';
				//监听事件 + 接收数据
				$scope.$on('UPDATE_NAME_CHILD2', function(event , data ){
					$scope.$broadcast('UPDATE_NAME_PARENT', data);
				});
			}

			function childCtrl1($scope, $rootScope){
				$scope.name = 'child1';
				//监听事件 + 接收数据
				$scope.$on('UPDATE_NAME_PARENT', function(event , data ){
					$scope.name = 'from ' + data.name + ', child1'
				});
			}

			function childCtrl2($scope, $rootScope){
				$scope.name = 'child2';
				$scope.initClick = function(){
					// 冒泡发布
					$scope.$emit('UPDATE_NAME_CHILD2', { name: 'child2' });
				} 
			}
		</script>
    </body>
</html>

在这里插入图片描述
注意:(1) $broadcast 会遍历所有子作用域,比较消耗性能;
(2) $on 的回调函数 中$broadcast 事件名称和$on事件名称不能相同,如果相同会造成死循环;
如下,会造成死循环:

$scope.$on('**NAME**', function(event , data ){
	$scope.$broadcast('**NAME**', data);
});
四. $emit, $on, $rootScope 实现发布/订阅

说明:$rootScope.$emit('EVENT', {}); 形式的发布可以用$rootScope.$on('EVENT', function(){}) 接收;

<!DOCTYPE HTML>
<html>
    <head>
		<meta charset="utf-8"/>
		<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
		<meta name="viewport" content="initial-scale=1, maximum-scale=3, minimum-scale=1, user-scalable=no"/>
		<title>标题</title>
    </head>
    <body ng-app="test">
		<div ng-controller="parentCtrl">
			<div ng-controller="childCtrl1">
				child1: <span ng-bind="name"></span><br>
			</div>
			<div ng-controller="childCtrl2">
				child2: <span ng-bind="name"></span><br>
				<button ng-click="initClick()">child2Click</button>
			</div>
		</div>
		
		<script src="bower_components/angular/angular.min.js"></script>
		<script>
			angular.module('test',[])
			.controller('parentCtrl', parentCtrl)
			.controller('childCtrl1', childCtrl1)
			.controller('childCtrl2', childCtrl2)
			.factory('pubSubService', pubSubService);

			function parentCtrl(){}

			function childCtrl1($scope, $rootScope, pubSubService){
				$scope.name = 'child1';
				pubSubService.subscribe('NAME_UPDATE',$scope, function(event, data){
					$scope.name = data.name;
				});
			}

			function childCtrl2($scope, $rootScope, pubSubService){
				$scope.name = 'child2';
				$scope.initClick = function(){
					pubSubService.publish('NAME_UPDATE', { name: 'I am from child2' });
				}
			}

			// 发布/订阅
			function pubSubService($rootScope){
				//发布
				var publish = function(eventName, data) {
					if (!eventName) {
						console.log('请输入事件名称');
					}
					$rootScope.$emit(eventName, data);
				};
				//订阅
				var subscribe = function(eventName, scope, func) {
					if (!eventName) {
						console.log('请输入事件名称');
					}
					var unbind = $rootScope.$on(eventName, func);
					scope.$on('$destroy', unbind);
				};

				return {
					publish :  publish ,
					subscribe :  subscribe
				};
			}
		</script>
    </body>
</html>

参考:https://stackoverflow.com/questions/11252780/whats-the-correct-way-to-communicate-between-controllers-in-angularjs/19498009#19498009

https://my.oschina.net/u/2434456/blog/602406

五. 粗暴执行另一作用域下的方法

angular.element(document.getElementById(‘另一个控制器的边界HTML标记 ID’)).scope().方法名();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值