`

通过angularjs的ng-repeat指令看scope的继承关系

阅读更多

ng-repeat指令的使用方式可以参考如下代码:

<!doctype html>
<html lang="en">
	<head>
	   <meta charset="utf-8">
	   <title>ng-repeat</title>
	   <script src="jquery-1.8.3.js"></script>
	   <script src="angular.js"></script>
	   <script>
			function wholeController($scope,$rootScope,$injector)
			{
				$scope.buttons = ["button1","button2","button3"];
				
				$scope.btnFunc = function(value){
					alert(value);
				};
			}
	   </script> 
	</head>
	
	<body ng-app>
		<div id="first" ng-controller="wholeController">
			<div id="buttonDiv">
				<input type="button" ng-repeat="button in buttons" id="btn{{$index}}" value="{{button}}" ng-click="btnFunc(button);"/>
			</div>
			<input type="button" value="test" ng-click="testFunc();">
		</div>	
	</body>
	
</html>

        这里需要注意:ng-click中访问button不需要使用{{button}}这种语法;而其他非angularjs环境下,必须通过{{button}}这种方式取值。ng-repeat指令中$index代表遍历的数组的索引,从0开始。
        我们知道ng-controller指令会创建一个新的作用域scope,测试代码如下:

<!doctype html>
<html lang="en">
	<head>
	   <meta charset="utf-8">
	   <title>ng-repeat</title>
	   <script src="jquery-1.8.3.js"></script>
	   <script src="angular.js"></script>
	   <script>
			//$scope是ng-controller指令新建的作用域
			function wholeController($scope,$rootScope,$injector)
			{
				alert($scope.$parent === $rootScope);//输出true
			}
	   </script> 
	</head>
	<body ng-app>
		<div id="first" ng-controller="wholeController">
		</div>	
	</body>
</html>

        我们可以使用angular.element(domElement).scope()方法来获得某一个DOM元素相关联的作用域。

<!doctype html>
<html lang="en">
	<head>
	   <meta charset="utf-8">
	   <title>ng-repeat</title>
	   <script src="jquery-1.8.3.js"></script>
	   <script src="angular.js"></script>
	   <script>
			function wholeController($scope,$rootScope,$injector)
			{
				$scope.buttons = ["button1","button2","button3"];
				
				$scope.testFunc = function(){
					 //拿到dom元素上关联的作用域
					 var scope0 = angular.element($("#btn0")[0]).scope();
					 var scope1 = angular.element($("#btn1")[0]).scope();
					 alert(scope0 == scope1);//输出false
					 
					 alert(scope0.$parent === $scope);//true
					 alert(scope1.$parent === $scope);//true
				};
			}
	   </script> 
	</head>
	
	<body ng-app>
		<div id="first" ng-controller="wholeController">
			<div id="buttonDiv">
				<input type="button" ng-repeat="button in buttons" id="btn{{$index}}" value="{{button}}" />
			</div>
			<input type="button" value="test" ng-click="testFunc();">
		</div>	
	</body>
	
</html>

        可以看到ng-repeat指令会新建作用域,而且是为循环中的每个dom元素新建一个作用域。通过F12调试,可以看到scope0和scope1的内容如下:

        可以看到scope0和scope1的$parent中都有一个buttons属性,这个属性就是从父作用域下继承得到的,很类似于javascript的原型链。

<!doctype html>
<html lang="en">
	<head>
	   <meta charset="utf-8">
	   <title>ng-repeat</title>
	   <script src="jquery-1.8.3.js"></script>
	   <script src="angular.js"></script>
	   <script>
			function wholeController($scope,$rootScope,$injector)
			{
				$scope.buttons = ["button1","button2","button3"];
				
				$scope.method1 = function(){
					 var scope0 = angular.element($("#btn0")[0]).scope();
					 scope0.buttons = ["a1","b1","c1"];
				};
				
				$scope.method2 = function(){
					 var scope0 = angular.element($("#btn0")[0]).scope();
					 scope0.$parent.buttons = ["a2","b2","c2"];
				};
				
				$scope.method3 = function(){
					var scope0 = angular.element($("#btn0")[0]).scope();
					scope0.buttons[0] = "a3";
					scope0.buttons[1] = "b3";
					scope0.buttons[2] = "c3";
				};
			}
	   </script> 
	</head>
	
	<body ng-app>
		<div id="first" ng-controller="wholeController">
			<div id="buttonDiv">
				<input type="button" ng-repeat="button in buttons" id="btn{{$index}}" value="{{button}}" />
			</div>
			<input type="button" value="method1" ng-click="method1();">
			<input type="button" value="method2" ng-click="method2();">
			<input type="button" value="method3" ng-click="method3();">
		</div>	
	</body>
	
</html>

        当点击method1、method2、method3的时候,我们希望将按钮button1、button2、button3替换掉。运行上面的代码可以发现:method2和method3都能成功达到目的,但是method1不能达到目的。原因分析如下:

        以于method2,它直接修改$parent的buttons,因此我们很容易看出它是可以达到替换的目的,调试查看$scope0如下:


        而method1的scope0.buttons = ["a1","b1","c1"];方法,会给scope0增加buttons属性并赋值(相当于重新赋值,没有改变原型),并不会影响$parents的buttons的值,所以就不能替换,如下所示:

        而对于methods方法中的scope0.buttons[0] = "a3";语句,首先会在当前作用域下找是否有buttons属性,发现没有,就会向父作用域(即JavaScript中原型链)查找,并找到了,然后修改,这里的修改实际上修改的就是$parents下的buttons,所以也生效了,如下所示:

        原因同http://bijian1013.iteye.com/admin/blogs/2221083中所说的对于原型的写有copy-on-write特性是一样的。

 

文章来源:http://blog.csdn.net/aitangyong/article/details/44086137

  • 大小: 53.9 KB
  • 大小: 78.8 KB
  • 大小: 84.9 KB
  • 大小: 91.2 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics