这篇,讲一下angularjs的ng-bind指令,多个控制器,以及手动触发angularjs的脏检查,我直接把代码贴,顺着代码讲。

  

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body ng-app="ngApp"> <div ng-controller="firstController">
<input type="text" ng-model="name"/>
<div ng-bind="name"></div>
<div ng-controller="secondController">
<input type="text" ng-model="name"/>
{{name}}
{{date}}
</div>
</div>
</body>
<script type="text/javascript" src="../public/javascripts/lib/angular.js"></script>
<script type="text/javascript">
alert(123);
var ngApp=angular.module('ngApp', []);
ngApp.controller("firstController",function($scope){
$scope.name="xixi";
});
ngApp.controller("secondController",function($scope){
setInterval(function(){
$scope.$apply(function(){
$scope.date=new Date();
});
},1000);
});
</script>
</html>

  1、ng-bind:在使用angularjs表达式{{name}}时,如果angularjs还没加载完毕,我们会看到页面直接把angularjs表达式当作字符串给渲染到html,这样显示不友好。这里推荐使用ng-bind,ng-bind在angularjs没有加载完毕的时候是不会解析执行的,一旦angularjs加载完毕的时候就会执行。运行上面的代码,在弹出alert的时候,起码没有使用ng-bind的地方就会直接显示angularjs的表达式,而是用了ng-bind的地方则是什么没有显示,关闭alert后,页面就显示了正常的数据。

  2、多个控制器:上面代码中,我们定义了两个控制器,firstController跟secondController,其中secondController是位于第一个firstController里面的,secondController里面没有name属性。我们在运行代码的时候,发现,第一个跟第二个控制器所控制的范围都显示了name的值,这是为什么呢?这其实跟javascript的作用域链是一样的。secondController里面没有找到name,就会往上一级找,刚好在firstController里面找打了name,所以两个控制器掌控的范围都显示了name的值。上面代码运行后,我们在第一个表单输入数值,发现,所以使用了name的地方都跟着变。而当在第二个表单,也就是第二个控制器掌控的作用域内,输入数值改变第二个控制器的model后,再在第一个表单输入值后,发现第二个的值不在变化了,这又是为什么呢?因为secondController此时内部会声明了name,而整个secondController运行的代码就在自己的作用域里面,同时由于上级的作用域是访问不到下级作用域的,所以不会影响secondController的值。注意,在第二个表单输入值,输入第一个表单的值,为啥第二个表单也跟着变呢?那是因为第二个表单往上面作用域寻找name变量,而不是第一个控制器所影响的。

  3、angularjs的apply:前面几篇的一些例子里面讲到,我们在控制器里面更改$scope的属性值,view也跟着变。但是,如果我们把上面代码的setInterval里面的$scope.$apply去掉,直接写上$scope.date=new Date(),这样页面的时间是不会改变的。这是因为控制器里面的$scope的属性值了,却没有进行属性的检查。大家应该知道,通常要知道一个变量是否更改,一般有两种情况,一是通过set调用赋值,二是通过脏检查,把原来的对象复制一份快照,在特定的时间,遍历现在的对象属性同快照的对象的属性一个一个的比较。这种策略要保留两份变量,且遍历对象比较每一个属性,这是有一定的性能问题的。在angularjs中,使用的就是脏检查这种策略。

  4、angularjs的脏检查策略:

    a) angularjs不会检查每一个对象,只有添加到html中的对象,才会添加为检查对象,即一个watcher。

    b) angularjs也不会检查每一个属性,只有属性被绑定以后,这个属性才会添加为检查属性。

    c) angularjs在初始化的时候,会为每一个对象的绑定属性添加为监听对象,即一个对象绑定了n个属性,则同时也就是添加了n个watcher。

  5、angularjs什么时候会进行脏检查呢?在angularjs系统中所有的方法,比如在controller初始化的时候,所以ng-开头的指令执行后都会触发脏检查。

  6、$apply手动触发脏检查。注意的时候,$apply只是进入了angularjs的执行上下文,真正触发脏检查的是$digest。在使用$apply的时候,如果不带参数,则会检查$scope里所有监听的属性,所以在使用的时候,建议带上参数。

  7、上面我们提到,出发脏检查的是$digest()方法,这个方法会出发$scope以及所有的子$scope的脏检查,而脏检查又出发了watcher,这样整个angularjs的数据双向绑定的机制就活起来了。虽然说触发脏检查的是$digest方法,但是不建议直接使用,而是建议使用$apply。$apply不是直接把信息传递给$digest的,而不是通过$eval这层过滤,如果$apply带的表达式不合法的话,$eval就会把错误发送给$exceptionHandler,只有合法的才会触发$digest,这样更加安全。

  本篇就写到这,后续会接着写angularjs其他方面的知识。

04、AngularJS的ng-bind、多个控制器和apply的更多相关文章

  1. AngularJS快速入门指南05:控制器

    AngularJS控制器用来控制AngularJS applications的数据. AngularJS控制器就是普通的JavaScript对象. AngularJS控制器 AngularJS app ...

  2. AngularJS(四)——ng-controller(控制器)

    前言 上篇大概说了一下指令的应用格式以及创建自定义指令方法,本篇重点介绍一些ng-controller都有哪些小作用. 内容 通过修改控制器部分,修改显示界面. Demo <div ng-app ...

  3. 走进AngularJs(二) ng模板中常用指令的使用方式

    通过使用模板,我们可以把model和controller中的数据组装起来呈现给浏览器,还可以通过数据绑定,实时更新视图,让我们的页面变成动态的.ng的模板真是让我爱不释手.学习ng道路还很漫长,从模板 ...

  4. 走进AngularJs(八) ng的路由机制

    在谈路由机制前有必要先提一下现在比较流行的单页面应用,就是所谓的single page APP.为了实现无刷新的视图切换,我们通常会用ajax请求从后台取数据,然后套上HTML模板渲染在页面上,然而a ...

  5. [angularjs] angularjs系列笔记(四)控制器

    Scope作用域 Scope作用域是应用在HTML视图和Js控制器之间的纽带 Scope是一个对象,有可用的属性和方法 根作用域 所有的应用都有一个$rootScope,它可以作用在ng-app指令包 ...

  6. AngularJS 笔记系列(四)控制器和表达式

    控制器:在 Angular 中控制器是一个函数,用来向作用域中添加额外的功能.我们用它来给作用域对象设置初始状态,并添加自定义行为. 使用方法: var app = angualr.module('a ...

  7. angularJS 第一天 使用模型与控制器绑定数据

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script sr ...

  8. AngularJS测试二 jasmine测试路由 控制器 过滤器 事件 服务

    测试应用 1.测试路由 我们需要检测路由是否在运作,是否找到了,或者是404了.我们要确认路由事件触发了,预期的模板是否真的加载了.既然路由会改变页面的地址(URL)和页面内容,我们需要检测路由是否被 ...

  9. AngularJS方法 —— angular.bind

    描述: 上下文,函数以及参数动态绑定,返回值为绑定之后的函数. 其中args是可选的动态参数,self在fn中使用this调用. 使用方法: angular.bind(self,fn,args ); ...

随机推荐

  1. The user specified as a definer ('root'@'%') does not exist

    The user specified as a definer ('root'@'%') does not exist 此种报错主要是针对访问视图文件引起的(没有权限) 解决方法: 2.进入mysql ...

  2. HDU 4832 Chess (DP)

    Chess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  3. 一、javase学习:数据库操作练习

    package JDBC_TEST; import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLExcept ...

  4. ceph与openstack对接

    对接分为三种,也就是存储为openstack提供的三类功能1.云盘,就好比我们新加的硬盘2.原本的镜像也放在ceph里,但是我没有选择这种方式,原因是因为后期有要求,但是我会把这个也写出来,大家自己对 ...

  5. mac--又发现了一款mac快捷键神器

    之前用applescript,还有keyboard maestro,前段时间用机械键盘的时候,用开源的karabiner重新设置机械键盘的键位. 今天因为网上抄的键位F4想换成Launchpad,所以 ...

  6. 神经网络(python源代码)

    神经网络的逻辑应该都是熟知的了,在这里想说明一下交叉验证 交叉验证方法: 看图大概就能理解了,大致就是先将数据集分成K份,对这K份中每一份都取不一样的比例数据进行训练和测试.得出K个误差,将这K个误差 ...

  7. 利用googleapis在日文系统中改善中文字

    加入以下两句 1. <head> <link rel="stylesheet" href="http://fonts.googleapis.com/ea ...

  8. sql模糊匹配中%、_的处理

    防sql注入之模糊匹配中%._处理: StringBuilder sbSql = new StringBuilder(); sbSql.Append(@"SELECT * from tabl ...

  9. L440 无线网卡:由于该设备有问题,Windows 已将其停止(代码 43)

    最近重装了系统,本来用的好好的,结果重启之后突然无线网卡不能用了,设备管理器老是黄色叹号!无线网卡设备状态:由于该设备有问题,Windows 已将其停止. (代码 43).      无线网卡型号:2 ...

  10. vertical-align 垂直居中

    基线:字母‘x’的底部: 中线:与基线的距离为小写字母x高度的一半(即0.5ex),而ex同font-size相关,大部分浏览器认为1ex = 0.5em(em同样也是相对单位,不是绝对单位),因此会 ...