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

AngularJS控制器详情

2016-05-19 20:33 597 查看

前言

为了对AngularJS的控制器了解更深,本次进行详细的测试。

AngularJS控制器基本使用

首先,定义一个控制器:
controller("XXName", function(……){});
然后绑定到HTML元素中去。这样,在该Controller中定义的值和方法,就可以在此HTML元素中使用。

控制器的作用域是$scope,该变量是一个普通的Json对象。 里面可以定义属性或者方法。在$scope中定义的变量和方法,只能在该controller中使用。
如果要使用全局的作用域,可以使用$rootScope,但是一般情况,尽量避免使用全局作用域。

Controller的定义方法,可以通过另外一种显式的DI注入:

xxx.controller("xxxName",["$scope","$rootScope",function($scope,$rootScope){……}   ]);

AngularJS控制器复用

Controller可以复用。同一个Controller可以在不同的元素中定义。
但是需要注意的是,每个Controller对应的控制域是不同的。也即$scope是独立的,都是继承于$rootScope。但是各自为政,互不干扰。



AngularJS控制器继承

控制器具有继承关系,默认所有的控制器中的$scope继承于$rootScope。继承的关系是$scope可以使用一切在$rootScope中的属性和方法,反过来就不行。
不过在,子Scope与父scope中,子scope可以覆盖父scope的属性。继承关系如下图:



见下面例子:
<!DOCTYPE html>
<html ng-app="exampleApp">
<head>
<meta charset="utf-8">
<title>控制器</title>
<script src="angular.js"></script>
<link href="bootstrap.css" rel="stylesheet" />
<link href="bootstrap-theme.css" rel="stylesheet" />
<script>
var app = angular.module("exampleApp", []);

app.controller("parentCtrl", function ($scope) {

$scope.data = "Hello, Kobe";	//初始值

$scope.reverseText = function () {
$scope.data = $scope.data.split("").reverse().join("");		//将数据分割反转再放进一个数组中
}

$scope.changeCase = function () {
var result = [];
angular.forEach($scope.data.split(""), function (char, index) {
result.push(index % 2 == 1
? char.toString().toUpperCase() : char.toString().toLowerCase());
});
$scope.data = result.join("");		//将奇数字母转小写,偶数字母转大写
};
});

app.controller("firstChildCtrl", function ($scope) {

$scope.changeCase = function () {
$scope.data = $scope.data.toUpperCase();		//将值转为大写
};
});

app.controller("secondChildCtrl", function ($scope) {

$scope.changeCase = function () {
$scope.data = $scope.data.toLowerCase();		//将值转为小写
};

$scope.shiftFour = function () {
var result = [];
angular.forEach($scope.data.split(""), function (char, index) {
result.push(index < 4 ? char.toUpperCase() : char);
});
$scope.data = result.join("");		//将前4字母转为大写,后面的不变
}
});
</script>
</head>
<body ng-controller="parentCtrl">

<div class="well">
<h4>Parent Controller</h4>
<div class="input-group">
<span class="input-group-btn">
<button class="btn btn-default" type="button"
ng-click="reverseText()">Reverse</button>
<button class="btn btn-default" type="button"
ng-click="changeCase()">Case</button>
</span>
<input class="form-control" ng-model="data">
</div>
</div>

<div class="well" ng-controller="firstChildCtrl">
<h4>First Child Controller</h4>
<div class="input-group">
<span class="input-group-btn">
<button class="btn btn-default" type="button"
ng-click="reverseText()">Reverse</button>
<button class="btn btn-default" type="button"
ng-click="changeCase()">Case</button>
</span>
<input class="form-control" ng-model="data">
</div>
</div>

<div class="well" ng-controller="secondChildCtrl">
<h4>Second Child Controller</h4>
<div class="input-group">
<span class="input-group-btn">
<button class="btn btn-default" type="button"
ng-click="reverseText()">Reverse</button>
<button class="btn btn-default" type="button"
ng-click="changeCase()">Case</button>
<button class="btn btn-default" type="button"
ng-click="shiftFour()">Shift</button>
</span>
<input class="form-control" ng-model="data">
</div>
</div>
</body>
</html>


效果:



AngularJS控制器 as 别名

angular在view上的绑定都必须使用直接的scope对象,对于controller来说我们也得必须注入$scope这个service。 angular从1.2版本开始带来了新语法Controller as。如下:

<!DOCTYPE html>
<html ng-app="exampleApp" >
<head>
<meta charset="utf-8">
<title>as别名</title>
<link href="bootstrap.css" rel="stylesheet" />
<link href="bootstrap-theme.css" rel="stylesheet" />
<script src="angular.js"></script>
<script>
var myApp = angular.module("exampleApp", []);
myApp.controller("dayCtrl", function () {
this.day = new Date();
});
</script>

</head>
<body >
<div class="panel" ng-controller="dayCtrl as dc">
<div class="page-header">
<h3>AngularJS as 测试</h3>
</div>
<h4>Now is {{dc.day | date:"yyyy-MM-dd HH:mm:ss"}}</h4>
</div>
</body>
</html>
效果:



其实controller的as语法,只是利用了$scope属性。将as后面的别名作为$scope中的对象。Angularjs源码实现如下:

if (directive.controllerAs) {
locals.$scope[directive.controllerAs] = controllerInstance;
}  
由此可以看到,controlleras只是$scope对象中的属性。因此,可以通过{{controllerAs.xxx}}访问到controllerInstance中的属性。

AngularJS中的事件传播机制

AngularJS中的作用域有一个非常有层次和嵌套分明的结构。其中它们都有一个主要的$rootScope(也就说对应的Angular应用或者ng-app),然后其他所有的作用域部分都是继承自这个$rootScope的,或者说都是嵌套在主作用域下面的。

那么在作用域之间如何通信呢?其中一个选择就是在应用程序作用域之中创建一个单例服务,然后通过这个服务处理所有子作用域的通信。

在AngularJS中还有另外一个选择:通过作用域中的事件处理通信。不过有所限制,例如,你并不能广泛的将事件传播到所有监控的作用域中。你必须选择是否与父级作用域或者子作用域通信。

$on、$emit和$broadcast使得event、data在controller之间的传递变的简单,关系如下:

$emit只能向parent controller传递event与data
$broadcast只能向child controller传递event与data $on用于接收event与data
$emit和$broadcast可以传多个参数,$on也可以接收多个参数

例子如下:
<!DOCTYPE html>
<html ng-app="exampleApp">
<head>
<meta charset="utf-8">
<title>App Event Test</title>
<script src="angular.js"></script>
<link href="bootstrap.css" rel="stylesheet" />
<link href="bootstrap-theme.css" rel="stylesheet" />
<script>
var app =angular.module("exampleApp", []);
app.controller('SelfCtrl', function($scope) {
$scope.click = function () {
$scope.$broadcast('to-child', 'child');
$scope.$emit('to-parent', 'parent');
}
});

app.controller('ParentCtrl', function($scope) {
$scope.$on('to-parent', function(event,data) {
console.log('ParentCtrl', data);       //父级能得到值
});

$scope.$on('to-child', function(event,data) {
console.log('ParentCtrl', data);       //子级得不到值
});

});

app.controller('ChildCtrl', function($scope){
$scope.$on('to-child', function(event,data) {
console.log('ChildCtrl', data);         //子级能得到值
});
$scope.$on('to-parent', function(event,data) {
console.log('ChildCtrl', data);         //父级得不到值
});

});

app.controller('BroCtrl', function($scope){
$scope.$on('to-parent', function(event,data) {
console.log('BroCtrl', data);          //平级得不到值
});

$scope.$on('to-child', function(event,data) {
console.log('BroCtrl', data);          //平级得不到值
});
});
</script>
</head>
<body >
<div ng-controller="ParentCtrl">                <!--父级-->
<div ng-controller="SelfCtrl">              <!--自己-->
<button type="button" class="btn btn-default" ng-click="click()">click me</button>
<div ng-controller="ChildCtrl"></div>   <!--子级-->
</div>
<div ng-controller="BroCtrl"></div>         <!--平级-->
</div>
<br>
</body>
</html>
效果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息