在
MVC
中,爲了方便維護,針對不一樣業務會使用不一樣的controller
。有時咱們須要在不一樣的controller
中共享數據,本文旨在解決這一問題。css
AngularJS中有一個$rootScope
對象,它是AngularJS中最接近全局做用域的對象,是全部$scope
對象的最上層,能夠簡單理解爲BOM
中的window對象或Node.js
中的global對象。最簡單的方式是直接將要共享的數據綁定到$rootScope
對象中:html
<!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所示:bootstrap
圖-1 頁面加載完畢app
圖-2 第一次點擊"Report Data"按鈕框架
圖-3 填寫信息,點擊"Share Data"按鈕ide
圖-4 再次點擊"Report Data"按鈕函數
這樣作解決了問題,在須要共享的數據量較少時能夠採用,但由於會污染全局做用域,所以十分不推薦使用這種方法。spa
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,有興趣的讀者能夠本身試驗一下。3d
$scope
能夠向其餘$scope
廣播或發送事件,其餘$scope
監聽事件並處理,從而實現通訊,也就是說能夠經過$scope
事件機制實現不一樣controller
之間的數據共享。$scope
事件機制包括如下三種方法:code
表-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
功能,詳情請參考這裏。
完。