AngularJS 本身已經提供了像指令 Directive 和 服務 Service 一類的方式,來實現數據和代碼的共享和複用,但在實際的項目開發中,或許是處於懶惰,亦或是爲了便利,總會想在兩個控制器之間,直接進行數據的共享通信,或者是函數與方法的調用,這裏我們就看看有哪些方法可以滿足這個要求。
單例服務
單例服務是 AngularJS 本身支持的數據和代碼共享方式,因爲是單例的,所有的控制器訪問的便是同一份數據。比如,下面的 Service 便可以實現:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
angular
.module( 'app' )
.service( 'ObjectService' ,
[ObjectService]);
function
ObjectService() {
var
list = {};
return
{
get:
function (id){
return
list[id];
},
set:
function (id,
v){
list[id]
= v;
}
};
}
|
在一個控制器中,調用 ObjectService.set('i',
1)
設置的數據,在其它控制器中,便可以通過 ObjectService.get('i')
來獲取。
廣播與事件
AngularJS 中在觸發事件和發送廣播時,都可以傳遞參數,可以通過這一特性,來實現數據的共享。與事件和廣播相關的,共有三個方法,分別是:
1.$emit():觸發事件,它可以向上傳遞數據,比如,子控制器向父控制器,還有控制器向 $rootScope
2.$broadcast():發送廣播,它可以向下傳遞數據,比如,父控制器向子控制器傳遞數據,或者 $rootScope 向任意控制器傳遞數據
3.$on():監聽事件與廣播,可以捕獲 $emit 和 $broadcast
可以將控制器之間的通信,分爲三種情形:
1.無直接關聯的控制器:使用 $rootScope.$emit()、$rootScope.$boardcast() 或 $scope.$emit 來發出數據,通過 $rootScope.$on() 來獲取數據
2.父控制器到子控制器:父控制器使用 $scope.$boradcast() 來發送數據,子控制器通過 $scope.$on() 來獲取數據
3.子控制器至父控制器:子控制器使用 $scope.$emit() 來發送數據,父控制器通過 $scope.$on() 來獲取數據
下面是簡單的用法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
angular
.module( 'app' )
.controller( 'OneController' ,
[ '$scope' ,
OneController]);
function
OneController($scope){
var
data = {value: 'test' };
$rootScope.$broadcast( 'open.notice.editor' ,
data);
}
angular
.module( 'app' )
.controller( 'AnotherController' ,
[ '$scope' ,
AnotherController]);
function
AnotherController($scope){
$scope.$on( 'open.notice.editor' ,
function (event,
data){
$scope.open(data);
$scope.$emit( 'notice.editor.opened' );
});
}
|
父控制器
如果兩個控制器共同擁有同一個父控制器,則可以通過父控制器來進行數據共享和通信。比如:
1
2
3
4
|
<div
ng-controller= "ParentController" >
<div
ng-controller= "ChildOneController" ></div>
<div
ng-controller= "ChildTwoController" ></div>
</div>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
angular
.module( 'app' )
.controller( 'ParentController' ,
[ '$scope' ,
ParentController]);
function
ParentController($scope){
$scope.data
= null ;
}
angular
.module( 'app' )
.controller( 'ChildOneController' ,
[ '$scope' ,
ChildOneController]);
function
ChildOneController($scope){
$scope.$parent.data
= 1;
}
angular
.module( 'app' )
.controller( 'ChildTwoController' ,
[ '$scope' ,
'$timeout' ,
ChildTwoController]);
function
ChildTwoController($scope, $timeout){
$timeout( function (){
console.log($scope.$parent.data);
},
1000);
}
|
全局或共用的變量
AngularJS 提供了對 window 和 localStorage 兩個變量的封裝,$window 和 $localStorage ,通過修改和監聽這兩個值,可以達到在控制器之間數據共享和通信的目的。方法如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
angular
.module( 'app' )
.controller( 'OneController' ,
[ '$scope' ,
'$window' ,
OneController]);
function
OneController($scope, $window){
$window.data
= 1;
}
angular
.module( 'app' )
.controller( 'AnotherController' ,
[ '$scope' ,
AnotherController]);
function
AnotherController($scope){
$scope.$watch( function (){
return
$window.data;
},
function (n){
$scope.windowData
= n;
});
}
|
其實,這種監聽修改的方式,也可以用在其它通信方式中。
元素綁定
AngularJS 中,可以通過一個元素,來獲取其上的控制器實例。通過這種方式便可以快速的獲取
修改某個控制器中的數據,或者調用這個控制器中的方法。比如:
1
2
3
|
<div
ng-controller= "AppController" >
<div
id= "div-a" ></div>
</div>
|
可以通過以下的方法,來獲取控制器實例:
1
|
var
instance = angular.element(document.getElementById( 'div-a' )).scope();
|
接着,便可以通過這個 instance 來調用控制器的方法,獲取和修改值了。無法是元素本身綁定有控制器,還是元素的父級元素綁定有控制器,都可以成功的獲取。
本文關於Angular控制器之間的數據共享與通信就介紹到這了,對angularjs共享數據相關知識感興趣的朋友可以一起學習,謝謝大家支持腳本之家。