angular js自学笔记(二)——作用域1.0

        今天终于拿到了《精通angular js》这本书,学长们力推的一本书,看了一天,豁然开朗,以下是对angular js中作用域的一些理解。

作用域1.0

控制器与$scope

        了解作用域,首先要理解angular js的控制器。控制器的主要职责是初始化作用域实例,那么问题来了,什么是作用域实例呢?学过Java的人都知道,Java中可以将很多方法和需要的属性封装到一个类中,方便其他类调用,在我个人看来,angular js里面就定义了一个scope类,而我们在html里面使用ng-controller标签(这个标签是由指令(Directives)定义的)时,会自动创建一个scope类的实例。这里就从angular js的运行来谈,由于我之前的学习时针对的Java和c语言,所以就拿Java来做对比,在dom加载完后,浏览器发现ng-app标签后,会先创建一个根作用域$root(这个root可以看成是Java中的类继承的根类),然后看到了ng-controller,于是又创建一个$scope(此时的$scope完全继承自$root,也就是说可以用$root的所有属性),也就是说在一个标签内的另一个标签如果创建作用域,如果没指明父作用域,那么它们之间就有个继承关系,说到这里,再回到控制器来,它的职责有个亮点“初始化”,也就是说控制器其实就是用来给$scope的属性赋值(这里的值可为数组,对象等,这个是js特有的特点)和方法

ng-repeat怎么创建作用域

        ng-repeat我在第一次接触时就喜欢上了它,因为有了它,我可以很简单的实现很多想法,它的作用是重复创建所在的标签,这个时候问题又来了,它这个语法"XXX in XXXs"(后面那个就表示复数啊)按照我上面说的原则,对应每个XXX,都有个新变量要暴露给$scope,而又不能覆盖之前的变量值,这个时候同名(XXX)的属性怎么创建作用域(属性也有自己的作用域,因为js的特点,属性也可以为对象等),angular js为了解决这个问题,使用了一个叫“模型值”(model values)的东东,用以辨别同名的属性作用域(也就是3个数字,如001)。



尝试

        对于以上的学习,我做了如下的尝试来验证:

        test.html

<span style="font-size:18px;"><html >
<head>
	<script type="text/javascript" src="angular.min.js"></script>
	<script type="text/javascript" src="test.js"></script>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body ng-app ng-init="appName='app'">
	$root.appName={{appName}}
	<div ng-controller="aCtrl">
		<hr>
		控制器作用域<br>
		使用父作用域的appName:<input ng-model="appName">
		$root.appName:{{appName}}
	    
	<br/>对names进行ng-repeat,给集合每个元素创建一个叫a的属性作用域
	  <div ng-repeat="a in names">
	  	<br/>
	  	使用a获取:{{a}}<br/>
	  	使用a.name获取:{{a.name}}<br>
	  </div>
	</div>
</body>
</html></span>
        test.js
<span style="font-size:18px;">var aCtrl = function($scope){
	$scope.names = [
		{name:"1"},
		{name:"2"},
	];
};</span>
        现在来看看浏览器的效果

   

       

        下面是ng-app($root)的作用域,  可以看到我定义的属性appName。

     

        再来看ng-controller($scope)的作用域,它里面也可以看到$root的appName,而且多了个属性names(这是我通过js给$scope创建的属性)

        下面再来看看ng-controller中通过ng-repeat创建的属性作用域

        第一个属性作用域,在里面有父作用域中的appName和names,而且又多了个a的属性,注意names集合中对象的值里多了个我在js里没有定义的$$hashKey,这个东西应该就是model values。


        第二个属性作用域也就大同小异了,可以看到唯一的区别就是$$hashKey的值


         既然子作用域可以用父作用域的值,那我就不免想到用子作用域更改值,会产生什么影响,以下是改变后浏览器的变化

         因为我的input标签与appName实现了双向数据绑定,可以看到我更改appName后,分割线上的{{appName}}无改变,而ng-controller($scope)中的{{appName}}改变了。


         来看看这个时候ng-app($root)的作用域,很明显appName没有改变,那么ng-controller($scope)里的appName为什么变了呢?

         带着疑问,我又看了ng-controller($scope)的作用域,没错,里面的appName改变了,再做了相关的查阅后,总结出一个原因:ng-controller生成的作用域创建了新的appName变量,而不是去修改$root中设定的appName的值,而如果想要修改,可以利用<input ng-model="$parent.appName">明确的引用父作用域来实现。

       
        以上是这篇笔记中的所有尝试。

TIP

        anguler js中官方定义的属性前都有个$符号,所以呢,我们创建自己的变量时就最好不要加$了,这样也方便查看,然后Firefox有个查看angular js作用域的工具,叫做Angscope,很有用,我就拿它来验证自己对作用域的猜想。


      未完待续(以上纯属个人感悟,仅供参考)......




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值