一. 概要
- 作用:存储应用数据模型的对象;监听 表达式 的变化并传播事件;
- 特点:基于原型链继承其父作用域属性的机制;
特殊情况:创建指令时,scope: {…},指创建隔离作用域;这种情况不会继承父作用域;
二. 双向绑定
在双向绑定时可能会遇到下面这种情况;
(1)
<!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="name" />
<div ng-controller="childCtrl">
child:<input ng-model="name" />
</div>
</div>
<script src="bower_components/angular/angular.min.js"></script>
<script src="bower_components/jquery/dist/jquery.min.js"></script>
<script>
angular.module('test',[])
.controller('parentCtrl', parentCtrl)
.controller('childCtrl', childCtrl);
function parentCtrl($scope){
$scope.name = 'test';
}
function childCtrl($scope){
}
</script>
</body>
</html>
原因:作用域继承与JS的原型继承是一样的,所有数据需要存储到对象中;
(2)
<!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: 暂时没有
<div ng-if="isShow" ng-controller="childCtrl">
child:<input ng-model="name" />
</div>
<div>test: {{name}}</div>
</div>
<script src="bower_components/angular/angular.min.js"></script>
<script src="bower_components/jquery/dist/jquery.min.js"></script>
<script>
angular.module('test',[])
.controller('parentCtrl', parentCtrl)
.controller('childCtrl', childCtrl);
function parentCtrl($scope, $timeout){
$scope.isShow = false;
$timeout(function(){
$scope.isShow = true;
},1000);
}
function childCtrl($scope){
}
</script>
</body>
</html>
原因:由于时间延迟,绑定关系没有建立;可以用ng-show代替ng-if 或者将数据存储到对象中;
<!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.name" />
<div ng-controller="childCtrl">
child:<input ng-model="user.name" />
</div>
</div>
<script src="bower_components/angular/angular.min.js"></script>
<script src="bower_components/jquery/dist/jquery.min.js"></script>
<script>
angular.module('test',[])
.controller('parentCtrl', parentCtrl)
.controller('childCtrl', childCtrl);
function parentCtrl($scope){
$scope.user = { name: 'test'};
}
function childCtrl($scope){
}
</script>
</body>
</html>
三. 继承
<!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: 暂时没有
<div ng-controller="childCtrl">
child:<input ng-model="user.name" />
</div>
</div>
<script src="bower_components/angular/angular.min.js"></script>
<script src="bower_components/jquery/dist/jquery.min.js"></script>
<script>
angular.module('test',[])
.controller('parentCtrl', parentCtrl)
.controller('childCtrl', childCtrl);
function parentCtrl($scope){
$scope.user = { name: 'test'};
}
function childCtrl($scope){
console.log('childCtrl');
console.log($scope);
}
</script>
</body>
</html>
上面的图片可以看出,child对应的scope并没有直接赋值user.name; 但是却可以获取到user.name;
原因:首先 js 会在当前作用域(也就是child对应的scop)中查找是否user.name,结果没有找到。然后沿着原型链找到 $parent所对应的作用域(也就是parent对应的scope)结果找到了。如果还没有找到,会沿着原型链继续找,直到根作用域 rootScop。
四. 创建子作用域的情况;
- ng-controller: 创建子作用域,并继承父作用域;
- ng-repeat: 每次循环都是一个独立的作用域, 创建的子作用域的个数和循环次数相等;并继承父作用域;
- ng-switch: 创建子作用域,并继承父作用域;
- ng-include:创建子作用域,并继承父作用域;
- directive (scope: true) :创建子作用域,并继承父作用域;
- directive(transclude: true) : 创建子作用域,并继承父作用域;
其他:
- directive(scope: {…}): 创建子作用域,但不继承父作用域;
- directive(scope: false): 不创建子作用域; 直接使用父作用域;