理解Angular中的$scope
2015-11-20 01:22
274 查看
Angular scope 使用的一些问题总结
在AngularJS中,child scope一般通过原型式继承自它的parent scope。(directive的scope属性为{...}的情况除外,因为它会创建独立的scope)。在指令中,默认使用的是parent scope,这意味着在指令中改变的任何属性都会反映到其parent scope中。设置scope:true 会在该指令中使用原型继承。scope的继承通常是直截了当的,但是当你尝试在child scope中使用定义在parent scope的双向数据绑定的时候,它可能就不像你期望的那样起作用了。原因是child scope会重写parent scope中的重名属性,这是原型式继承的一个特征。
注意:ng-repeat, ng-switch, ng-view, ng-include 都会创建新的child scope,上述问题通常出现在这些指令的使用过程中。具体可以看看这个例子
要避免上面的问题有以下几个方法:
总是在ng-model中使用 '.' 即ng-model使用一个对象而不是一个基本类型的值
这样:<input type="text" ng-model="someObj.prop1">
而不是: <input type="text" ng-model="prop1">
如果你实在要使用基本类型,可以参照下面两个方法
1.在child scope中使用 $parent.parentScopeProperty,它会阻止child scope创建自己的属性覆盖parent scope上的同名属性
2.在parent scope中定义一个方法,然后在child scope中调用,将基本类型值通过参数传递给parent
Angular scope 的继承
以下会创建新的scope,并且原型式继承自parent scope:ng-repeat, ng-include, ng-switch, ng-view, ng-controller, 设置了scope: true的指令, 设置了transclude: true的指令
以下会创建新的scope,但是不通过原型式继承自parent scope
设置了 scope: {....}. 这样会创建一个独立的scope
注意,默认情况下,自定义指令并不会创建新的scope,scope:false是默认值
ng-include
假设在controller.js中有以下代码
// 定义一个基本类型的值 $scope.myPrimitive = 50; // 定义一个对象 $scope.myObject = {aNumber: 11};
html代码
<script type="text/ng-template" id="/tpl1.html"> <input ng-model="myPrimitive"> </script> <div ng-include src="'/tpl1.html'"></div> <script type="text/ng-template" id="/tpl2.html"> <input ng-model="myObject.aNumber"> </script> <div ng-include src="'/tpl2.html'"></div>
上面每个ng-include都会产生一个新的child scope, 原型继承自parent scope
![](http://images2015.cnblogs.com/blog/810695/201511/810695-20151120000800061-156177330.png)
看看结果如下:
![](http://images2015.cnblogs.com/blog/810695/201511/810695-20151120003025358-855168788.png)
第一个input的ng-model是一个基本类型,它不能与parent scope中的表达式实现双向数据绑定,原因在于child scope通过原型继承属性自其parent scope,对于基本类型的值,child scope重写parent scope中的重名属性。
![](http://images2015.cnblogs.com/blog/810695/201511/810695-20151120003450124-6620611.png)
第二个input的ng-model是一个对象,它可以实现双向数据绑定,当ngModel查找一个对象时,它会一直查找到parent scope.
![](http://images2015.cnblogs.com/blog/810695/201511/810695-20151120003800124-206790334.png)
我们也可以对第一个input进行改写如下:
<input ng-model="$parent.myPrimitive">
![](http://images2015.cnblogs.com/blog/810695/201511/810695-20151120003940671-1107332005.png)
这里$parent是child scope下的一个属性,该属性指向parent scope
或者在parent scope中定义一个方法来改变基本类型的值,在child scope调用该方法,看代码
// controller.js $scope.setMyPrimitive = function (value){ $scope.myPrimitive = value; }
<input ng-model="myPrimitive" class="form-control" ng-change="setMyPrimitive(myPrimitive)">
效果如下:可以看到可以正常地进行双向数据绑定了
![](http://images2015.cnblogs.com/blog/810695/201511/810695-20151120004921343-1485120830.png)
[b]ng-repeat[/b]
假设有如下代码:controller.js
$scope.myArrayOfPrimitives = [ 11, 22 ]; $scope.myArrayOfObjects = [{num: 101}, {num: 202}]
html代码如下:
<ul><li ng-repeat="num in myArrayOfPrimitives"> <input ng-model="num"></input> </li> </ul> <ul><li ng-repeat="obj in myArrayOfObjects"> <input ng-model="obj.num"></input> </li> </ul>
对每一个li,ng-repeat都创建一个新的scope,继承自parent scope,但是同时会将遍历的变量(第一个ul中为num) 作为新的child scope的一个属性,myArrayOfPrimitives[num]的值作为该属性的属性值。
angular中ng-repeat的源码如下:
childScope = scope.$new(); // child scope prototypically inherits from parent scope ... childScope[valueIdent] = value; // creates a new childScope property
如果在遍历数组中的每个item是一个基本类型(myArrayOfPrimitives),该item的值会被分配给新child scope的属性,改变这个属性的值(例如使用ng-model),不会改变parent scope中的数组。在第一个ul中,每个child scope有一个num属性独立于数组myArrayOfPrimitives。
![](http://images2015.cnblogs.com/blog/810695/201511/810695-20151120011440640-1781478395.png)
如果我们希望改变在item中改变parent scope中的数组,我们需要将model变为一个数组对象
所以,如果数组中的每个item都是一个对象,该对象的一个引用会被分配给child scope的属性,改变child scope的属性值也会改变parent scope中的数组的引用。
![](http://images2015.cnblogs.com/blog/810695/201511/810695-20151120011949655-412704942.png)
今天先搞到这里,原文地址 Understanding Scopes
相关文章推荐
- find命令的exec参数使用---Linux学习笔记
- UVA 11992 Fast Matrix Operations 线段树
- 理解Linux系统/etc/init.d目录和/etc/rc.local脚本
- 网站初步收工---www.dkill.net
- CentOS 6.4 文件夹打开方式
- CentOS 6.4 文件夹打开方式
- LINK : fatal error LNK1181: cannot open input file ‘xxx.obj’
- shell入门-awk-3
- java 执行linux命令或shell脚本方法
- CentOS下crontab执行java程序
- find命令---Linux学习笔记
- zabbix自定义监控网卡流量脚本
- 初识Linux--Federa
- [ecshop 资料]ECshop彻底去版权(同时适用于2.7.3)
- 响应式网站案例及源码
- “甜心作坊”网站设计与制作
- SSH Secure Shell Client中文乱码的解决办法
- xshell链接虚拟机Ubuntu
- xshell远程连接设置
- linux主机无法登陆