这篇,讲一下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. Regex

    1. regex with variable example: find the number and put a parenthese around the number. output: a(52 ...

  2. 使用dd命令克隆整个系统(转)

    神奇的ghost的原理是什么呢?不就是数据复制吗?Linux下的dd命令不就是最强大的数据复制工具!          既然如此,我为什么要使用g4l这样复杂的工具呢?一条dd命令不就可以帮我实现任意 ...

  3. JAVA 中数据库连接的方法之一

    /** * 数据库连接类 * */ package com.cn.MysqlConnect; import java.sql.Connection;import java.sql.DriverMana ...

  4. Android新建数据库和建表demo

    public class DBHelper extends SQLiteOpenHelper{ public final static String DATABASENAME ="diary ...

  5. mock测试框架Mockito

    无论是敏捷开发.持续交付,还是测试驱动开发(TDD)都把单元测试作为实现的基石.随着这些先进的编程开发模式日益深入人心,单元测试如今显得越来越重要了.在敏捷开发.持续交付中要求单元测试一定要快(不能访 ...

  6. asp.net Word Document Open return null

  7. MVC 构建图片/文件选择器 参考其它CMS功能

    实现结果,如下 点击选择图片,弹出一个iframe框 顶部默认图片根目录,依次下面是文件列表 底部是选择的文件地址,以及上传新的图片和文件 加载iframe 调用js方法 function initF ...

  8. windows下调用发送邮件程序项*发送邮件

    #include <windows.h>int _tmain(int argc, _TCHAR* argv[]){ ShellExecute(NULL, _T("open&quo ...

  9. wget下载工具

    转自于:http://www.jb51.net/LINUXjishu/86326.html 1.使用wget下载单个文件  e.g. wget http://cn.wordpress.org/word ...

  10. c++11 实现单例模式

    C++11出来后,里面新增加了好多好用的功能 下面的单例就是使用了C++11中的标准库中的mutex和unique_prt 进行内存管理的. 此单例模式不用担心内存的释放问题 #pragma once ...