04、AngularJS的ng-bind、多个控制器和apply

时间:2021-08-09 20:39:41

  这篇,讲一下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&lpar;二&rpar; ng模板中常用指令的使用方式

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

  4. 走进AngularJs&lpar;八&rpar; ng的路由机制

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

  5. &lbrack;angularjs&rsqb; 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&period;bind

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

随机推荐

  1. win7优化

  2. javascript 简单加解密

    //加密 function MyEncrypt(txt) { var sb = ""; var rand = 0; for (var i=0;i<txt.length;i++ ...

  3. 初识Windows窗体&lpar;包括各种控件&comma;属性&comma;方法&rpar;

    什么是Wind ows窗体? 顾名思义,win dows窗体就是将一些所必须的信息通过窗体的形式展示给客户看.例如:我们经常玩的QQ登陆界面,微信登陆界面,等等,都是以窗体的形式将信息展示给我们看的. ...

  4. FastDFS在centos上的安装配置与使用

    FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储.文件同步.文件访问(文件上传.文件下载)等,解决了大容量存储和负载均衡的问题.特别适合以文件为载体的在线服务.(百 ...

  5. css 定义hr的几种样式

    <style type="text/css"> <!-- .hr0{ height:1px;border:none;border-top:1px dashed # ...

  6. Linux Debugging(五)&colon; coredump 分析入门

    作为工作几年的老程序猿,肯定会遇到coredump,log severity设置的比较高,导致可用的log无法分析问题所在. 更悲剧的是,这个问题不好复现!所以现在你手头唯一的线索就是这个程序的尸体: ...

  7. node&period;js生成二维码

    var http = require('http'); var qs = require('querystring'); var qrImg = require('qr-image'); var se ...

  8. Luogu2264 树上游戏(点分治)

    要统计所有路径的信息,那我们考虑点分治,每次算经过分治中心的路径的贡献.然而路径的颜色数量实在是不好统计,既然只需要求从每个点出发的所有路径的颜色数量之和,那换一种思路,改为求从每个点出发包含某种颜色 ...

  9. How to click on a point on an HTML5 canvas in Python selenium webdriver

    https://*.com/questions/29624949/how-to-click-on-a-point-on-an-html5-canvas-in-python-se ...

  10. Spring注解 &commat;Configuration

    Spring注解 @Configuration 一.@Configuration的作用 二.@Configuration的Spring容器启动方式 三.不加@Configuration的@Bean的解 ...