您的位置:首页 > Web前端 > AngularJS

AngularJS(三)——在多个AngularJS controller之间共享数据

2015-08-13 18:07 871 查看
MVC
中,为了方便维护,针对不同业务会使用不同的
controller
。有时我们需要在不同的
controller
中共享数据,本文旨在解决这一问题。

1. 使用$rootScope直接绑定

AngularJS中有一个
$rootScope
对象,它是AngularJS中最接近全局作用域的对象,是所有
$scope
对象的最上层,可以简单理解为
BOM
中的window对象或
Node.js
中的global对象。最简单的方式是直接将要共享的数据绑定到
$rootScope
对象中:
<!DOCTYPE html>
<html ng-app="exampleApp">
<head>
<meta charset="utf-8">
<title>Share Between Ctrls</title>
<script src="lib/angular.js"></script>
<link href="css/bootstrap.min.css" rel="stylesheet" />
<link rel="stylesheet" href="css/bootstrap-responsive.min.css">
<script>
var app = angular.module("exampleApp", []);
app.controller("FirstController", function($rootScope, $scope) {
$scope.shareObject = function (obj) {
$rootScope.person = obj || {};
};
});

app.controller("SecondController", function($rootScope, $scope) {
$scope.reportData = function() {
var reportString = "",
person = $rootScope.person || {};
for(var i in person) {
reportString += "person's " + i + " is " + person[i] + "\n";
}
alert(reportString);
};
});
</script>
</head>
<body>
<div class="well" ng-controller="FirstController">
<input type="text" ng-model="person.name" placeholder="Input Your Name" />
<input type="text" ng-model="person.age" placeholder="Input Your Age" />
<input type="text" ng-model="person.sex" placeholder="Input Your Sex" />
<button class="btn btn-primary" ng-click="shareObject(person)">Share Data</button>
</div>
<div class="well" ng-controller="SecondController">
<button class="btn btn-primary" ng-click="reportData()">Report Data</button>
</div>
</body>
</html>
整个效果如图-1 ~ 图-4所示:

图-1 页面加载完毕

图-2 第一次点击"Report Data"按钮

图-3 填写信息,点击"Share Data"按钮

图-4 再次点击"Report Data"按钮这样做解决了问题,在需要共享的数据量较少时可以采用,但因为会污染全局作用域,因此十分不推荐使用这种方法。

2. 使用
service
共享数据

...
<script>
var app = angular.module("exampleApp", []);
//需要将DataShareService注入
app.controller("FirstController", function($scope, DataShareService) {
$scope.person = {};
$scope.shareObject = function (obj) {
//赋值
DataShareService.shareObject = obj;
};
});

//需要将DataShareService注入
app.controller("SecondController", function($scope, DataShareService) {
var person = {};
$scope.reportData = function() {
var reportString = "",
person = DataShareService.shareObject; //取值
for(var i in person) {
reportString += "person's " + i + " is " + person[i] + "\n";
}
alert(reportString);
};
});

//自定义service,在多个controller之间共享数据
app.service("DataShareService", function() {
//无需定义其他变量,无需return,如果使用factory()则至少需要return一个空对象
});
<!--
这里的
app.factory()
可以替换为
app.constant()
app.value()
app.service()
-->
</script>
...
最终实现的效果和使用
$rootScope
直接绑定完全相同,优点是解决了全局作用域被污染问题。有关最后
app.factory()
的替换问题可以参考之前的一篇博客,使用AngularJS自定义service,有兴趣的读者可以自己试验一下。

3. 使用$scope事件机制

$scope
可以向其他
$scope
广播或发送事件,其他
$scope
监听事件并处理,从而实现通信,也就是说可以通过
$scope
事件机制实现不同
controller
之间的数据共享。
$scope
事件机制包括以下三种方法:

表-1 有关$scope事件机制的三个方法其中,
$broadcast(name, args)
为父级
$scope
向子级
$scope
发送事件,
$emit(name, args)
为子级
$scope
向父级
$scope
发送事件,
$on(name, handler)
为监听事件的函数,
handler
参数为对事件进行处理的函数,该函数包含两个参数:event和args,分别为事件对象和发送事件时传递的args参数。这里我们不存在
controller
的嵌套,所有的
$scope
为同级,需要使用“祖宗级”
$rootScope
进行广播。有关
controller
嵌套和继承的问题会在之后的博文中讲到。使用
$scope
事件机制处理数据共享的
JS
代码如下所示,由于
HTML
代码与之前相同,故省略:
...
<script>
var app = angular.module("exampleApp", []);
app.controller("FirstController", function($rootScope, $scope) {
$scope.person = {};
$scope.shareObject = function (obj) {
obj = obj || {};
//将事件以"ShareObjectEvent"为名进行广播
$rootScope.$broadcast("ShareObjectEvent", obj);
};
});

app.controller("SecondController", function($scope) {
//监听"ShareObjectEvent"事件
$scope.$on("ShareObjectEvent", function(event, args) {
person = args;
});
$scope.reportData = function() {
var reportString = "";
for(var i in person) {
reportString += "person's " + i + " is " + person[i] + "\n";
}
alert(reportString);
};
});
</script>
...
最终实现的效果和使用
$rootScope
直接绑定完全相同。最后需要补充的一点是,使用$scope事件机制与前两种方法相比有着实时性的优势,即数据的变化能够及时被响应,如果想在使用前两种方法时达到监听数据变化实时响应的效果,需要用到AngularJS的
$watch
$watchCollection
功能,详情请参考这里。完。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息