AngularJs html compiler详解及示例代码


Posted in Javascript onSeptember 01, 2016

原文再续,书接上回。。。依旧参考http://code.angularjs.org/1.0.2/docs/guide/compiler

一、总括

Angular的HTML compiler允许开发者自定义新的HTML语法。compiler允许我们对任意HTML元素或属性,甚至是新的HTML标签、属性(如<beautiful girl=”cf”></beautiful >)附加行为。Angular将这些附加行为称为directives。

HTML有很多专门格式化静态文档的预定义HTML样式结构(可以告诉浏览器如何显示标记的内容)。假设某东东需要被居中,而我们不需要教浏览器如何去做(此处省略N字)。我们只需要简单地对需要居中的标签加入align=”center”即可。这就是声明式语言(declarative language)的牛X之处。

但是声明式语言也有它的局限性,即你不能告诉浏览器如何处理在预定义范围外的语法。例如,我们不能很简单地告诉浏览器如何让文本在浏览器的1/3处对齐。所以,我们正需要一个让浏览器与时俱进,学学新语法的途径。

Angular预先绑定了一些对构建应用有帮助的directives。我们也可以自己创建属于自己应用的独特的directives。这些directive扩展将成为我们自己的应用的“特定领域语言”(Domain Specific Language)。

这些编译将仅仅发生在浏览器端,无须服务端或者预编译步骤。

二、Compiler

Compiler作为Angular的一个服务(Service),负责遍历DOM结构,寻找属性。编译过程分成两个阶段:

1. 编译(Compile):遍历DOM节点树,收集所有directives。返回结果是一个链接函数(linking function)。

2. 链接(Link):将directives绑定到一个作用域(scope)中,创建一个实况视图(live view)。在scope中的任何改变,将会在视图中得到体现(更新视图);任何用户对模版的活动(改变),将会体现在scope model中(双向绑定)。这使得scope model能够反映正确的值。

一些directives,诸如ng-repeat,会为每一个在集合(collection)中的元素复制一次特定的元素(组合)。编译和链接两个阶段,使性能得以提升。因为克隆出来的模版(template)只需要编译一次,然后为每一个集合中的元素进行一次链接(类似模版缓存)。

三、Directive

Directive是一个行为,在编译过程中遇到特定的HTML结构时,它会被触发。Directives可以放置在元素的name、attribute、class甚至注释中。以下是几种引用ng-bind(一个内置directive)的方法:

<span ng-bind="exp"></span>

<span class="ng-bind: exp;"></span>

<ng-bind></ng-bind>

<!-- directive: ng-bind exp -->

Directive只是一个当编译器在DOM中遇到时会执行的一个函数(function)。directive API文档中有详细讲解如何创建一个directive。

下面是一个样例,可以让一个元素跟你的鼠标玩躲猫猫……

<!DOCTYPE html>
<html lang="zh-cn" ng-app="HideAnkSeek">
<head>
  <meta charset="UTF-8">
  <title>躲猫猫</title>
  <style type="text/css">
    .ng-cloak {
      display: none;
    }
  </style>
</head>
<body>
<span class="ng-cloak" wildcat>一碰我就跑~~来点我啊~~</span>
<script src="../angular-1.0.1.js" type="text/javascript"></script>
<script type="text/javascript">
  angular.module("HideAnkSeek", []).directive("wildcat", function ($document) {
    var maxLeft = 400,maxTop = 300;
    var msg = ["我闪~~", "抓我呀~~~", "雅蠛蝶~~", "噢耶~~", "你真逊~!","就差那么一点点了!","继续吧~~总有一天我会累的"];
    return function (scope, element, attr) {
      element.css({
        "position":"absolute",
        "border":"1px solid green"
      });
      element.bind("mouseenter", function (event) {
        element.css({
          "left":parseInt(Math.random() * 10000 % maxLeft) + "px",
          "top":parseInt(Math.random() * 10000 % maxTop) + "px"
        }).text(msg[parseInt(Math.random() * 10000 % msg.length)]);
      }).bind("click",function (event) {
            element.text("噢My Lady Gaga。。。被你逮到了。。。");
            element.unbind("mouseenter");
          });
    };
  });
</script>
</body>
</html>

在任意元素中添加“wildcat”这个属性,将会使该元素拥有新的行为。就这样,我们教会了浏览器如何处理会躲猫猫的元素(放心,你不是在某个房间,你不会挂的-_-!)。我们通过这一途径扩展了浏览器的“词汇量”。对于任意一个熟悉HTML规则的人,这算是一个比较自然的方式。

现在已经夜深了,明天继续。。。广告之后见

===================华丽的分割线=======================

四、理解视图(View)

外面有许多模版系统,它们通常都通过模版字符串与数据进行连接,生成最终的HTML字符串,并将结果通过innerHTML属性写入某元素里。

AngularJs html compiler详解及示例代码

 

这意味着任何数据发生改变时,都需要重新将数据、模版合并成字符串,然后当作innerHTML写回对应元素中。这里存在一些问题:(这里直译实在没法懂..唯有YY)假设有这么一个场景,模版里包含输入框。用户对在输入框进行输入,模版同步更新。普通模版通过innerHTML、字符串与数据连接的方式更新视图,这样会打断用户的输入,体验不好。

Angular是与众不同的。Angular编译器(compiler)通过directives处理DOM,而不是通过处理字符串模版。处理结果是一个与scope model组合并生成实时模版的链接函数(linking function)。视图与scope model的绑定对我们来说是透明的。开发者无须为更新视图、model做任何动作。而且,因为没有使用innerHTML更新视图模版,所以用户输入不会被打断。此外,angular directives不仅可以绑定文本值,而且还可以是拥有行为的结构(behavioral constructs)。

AngularJs html compiler详解及示例代码

Angular的这个处理方式,产生了一个稳定的DOM。这意味着在DOM元素的生命周期里,一直与某model的实例绑定着,这个关系不会发生改变。这也意味着代码可以保持对某DOM对象的引用,对其注册事件函数,并且这个引用不会被模版数据合并所销毁。

Javascript 相关文章推荐
javascript管中窥豹 形参与实参浅析
Dec 17 Javascript
自己实现string的substring方法 人民币小写转大写,数字反转,正则优化
Sep 02 Javascript
javascript 实现 秒杀,团购 倒计时展示的记录 分享
Jul 12 Javascript
js propertychange和oninput事件
Sep 28 Javascript
js实现浮动在网页右侧的简洁QQ在线客服代码
Sep 04 Javascript
快速掌握WordPress中加载JavaScript脚本的方法
Dec 17 Javascript
javascript瀑布流布局实现方法详解
Feb 17 Javascript
jQuery height()、innerHeight()、outerHeight()函数的区别详解
May 23 Javascript
浅析javascript中的Event事件
Dec 09 Javascript
详解vue 不同环境配置不同的打包命令
Apr 07 Javascript
vue中的双向数据绑定原理与常见操作技巧详解
Mar 16 Javascript
如何管理Vue中的缓存页面
Feb 06 Vue.js
AngularJs bootstrap搭载前台框架——js控制部分
Sep 01 #Javascript
使用jQuery的toggle()方法对HTML标签进行显示、隐藏的方法(示例)
Sep 01 #Javascript
AngularJs bootstrap搭载前台框架——基础页面
Sep 01 #Javascript
使用jQuery.Qrcode插件在客户端动态生成二维码并添加自定义Logo
Sep 01 #Javascript
jQuery中的insertBefore(),insertAfter(),after(),before()区别介绍
Sep 01 #Javascript
AngularJs bootstrap搭载前台框架——准备工作
Sep 01 #Javascript
JS仿hao123导航页面图片轮播效果
Sep 01 #Javascript
You might like
PHP实现返回JSON和XML的类分享
2015/01/28 PHP
Codeigniter中集成smarty和adodb的方法
2016/03/04 PHP
PHP框架实现WebSocket在线聊天通讯系统
2019/11/21 PHP
jquery isEmptyObject判断是否为空对象的函数
2011/02/14 Javascript
JavaScript移除数组元素减少长度的方法
2013/09/05 Javascript
js实现收缩菜单效果实例代码
2013/10/30 Javascript
超级好用的jQuery圆角插件 Corner速成
2014/08/31 Javascript
在HTML代码中使用JavaScript代码的例子
2014/10/16 Javascript
js实现window.open不被拦截的解决方法汇总
2014/10/30 Javascript
jQuery实现动态添加和删除一个div
2015/08/12 Javascript
jQuery实现简单的DIV拖动效果
2016/02/19 Javascript
javascript原生ajax写法分享
2016/04/10 Javascript
原生js实现addClass,removeClass,hasClass方法
2016/04/27 Javascript
简洁实用的BootStrap jQuery手风琴插件
2016/08/31 Javascript
AngularJs Modules详解及示例代码
2016/09/01 Javascript
JS中this上下文对象使用方式
2016/10/09 Javascript
Angular 1.x个人使用的经验小结
2017/07/19 Javascript
JavaScript实现计算圆周率到小数点后100位的方法示例
2018/05/08 Javascript
浅谈ElementUI中switch回调函数change的参数问题
2018/08/24 Javascript
利用vue重构有赞商城的思路以及总结整理
2019/02/21 Javascript
使用JavaScript获取Django模板指定键值数据
2020/05/27 Javascript
JavaScript中交换值的10种方法总结
2020/08/18 Javascript
Python中的异常处理学习笔记
2015/01/28 Python
Nginx搭建HTTPS服务器和强制使用HTTPS访问的方法
2015/08/16 Python
Python中的并发处理之asyncio包使用的详解
2018/04/03 Python
Python 私有属性和私有方法应用场景分析
2020/06/19 Python
Python基于callable函数检测对象是否可被调用
2020/10/16 Python
为什么Runtime.exec(“ls”)没有任何输出?
2014/10/03 面试题
《桃花心木》教学反思
2014/02/17 职场文书
广告艺术设计专业自荐书
2014/07/08 职场文书
2014年党员教师自我剖析材料
2014/09/30 职场文书
公司租房协议书范本
2014/10/08 职场文书
工程技术员岗位职责
2015/04/11 职场文书
绿色环保倡议书
2015/04/28 职场文书
计划生育责任书
2015/05/09 职场文书
小学生红领巾广播稿
2015/08/19 职场文书