AngularJS HTML编译器介绍


Posted in Javascript onDecember 06, 2014

概览

AngularJS的HTML编译器能让浏览器识别新的HTML语法。它能让你将行为关联到HTML元素或者属性上,甚至能让你创造具有自定义行为的新元素。AngularJS称这种行为扩展为“指令”

HTML在编写静态页面时,有很多声明式的结构来控制格式。比如你要把某个内容居中,你不必告诉浏览器“去找到窗口的中点位置,然后跟内容的中间结合”。你只需要添加一个 align="center" 的属性给需要内容居中的元素就行了。这就是声明式语言的强大之处。

但是声明式语言也有力所不能及的地方,原因之一在于你不能用它来让浏览器识别新的语法。比如说,你不要内容居中,而是居左到1/3,这时它就做不到了。所以我们需要一个办法让浏览器能学会新的HTML语法。

AngularJS生来自带一些对创建APP非常有用的指令。我们也希望你能自己创造一些对你自己的应用有用的指令。这些扩展的指令就是你创建APP的 “特定领域语言(Domain Specific Language)”。

编译的过程都会在浏览器端发生;服务器端不会参与到其中的任何步骤,也不会做预编译。

编译器(complier)

编译器是AngularJS提供的一项服务,它通过遍历DOM来查找和它相关的属性。整个编译的过程分为两个阶段。

1.编译: 遍历DOM并且收集所有的相关指令,生成一个链接函数。

2.链接: 给指令绑定一个作用域,生成一个动态的视图。作用域模型的任何改变都会反映到视图上,并且视图上的任何用户操作也都会反映到作用域模型。这使得作用域模型成为你的业务逻辑里唯一要关心的东西。

有一些指令,比如ng-repeat会为数据集合里的每一项DOM元素都克隆一次。将整个编译过程分为编译和链接两个阶段的作法改善了整体的性能,因为克隆出来的模板总共只需要被编译一次,然后链接到各自的模型实例上就行了。

指令

指令指示的是“当关联的HTML结构进入编译阶段时应该执行的操作”。指令可以写在元素的名称里,属性里,css类名里,注释里。下面有几个功能相同的使用ng-bind指令的例子。

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

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

<ng-bind></ng-bind>

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

指令本质上只是一个当编译器编译到相关DOM时需要执行的函数。你可以在指令API文档中找到更详尽的关于指令的资料。

下面是一条能让元素变得可拖拽的指令。注意<span>元素里的那个draggable属性。

index.html:

<!doctype html>

<html ng-app="drag">

  <head>

    <script src="http://code.angularjs.org/angular-1.1.0.min.js"></script>

    <script src="script.js"></script>

  </head>

  <body>

    <span draggable>Drag ME</span>

  </body>

</html>

script.js:

angular.module('drag', []).

directive('draggable', function($document) {

    var startX=0, startY=0, x = 0, y = 0;

    return function(scope, element, attr) {

      element.css({

       position: 'relative',

       border: '1px solid red',

       backgroundColor: 'lightgrey',

       cursor: 'pointer'

      });

      element.bind('mousedown', function(event) {

        startX = event.screenX - x;

        startY = event.screenY - y;

        $document.bind('mousemove', mousemove);

        $document.bind('mouseup', mouseup);

      });
      function mousemove(event) {

        y = event.screenY - startY;

        x = event.screenX - startX;

        element.css({

          top: y + 'px',

          left:  x + 'px'

        });

      }
      function mouseup() {

        $document.unbind('mousemove', mousemove);

        $document.unbind('mouseup', mouseup);

      }

    }

 });

通过加入draggable属性可以让任何HTML元素都实现这个新的行为。我们这种改进的优美之处在于我们给了浏览器新能力。我们用了一种只要开发者熟悉HTML规则,就会举得很自然的方式扩展了浏览器理解新行为新语法的能力。

理解视图

网上有很多的模板系统。他们大多数都是“将静态的字符模板和数据绑定,生成新字符,然后通过innerHTML插入到页面元素中”。

这意味着数据上的任何改变,都会导致数据要重新和模板结合生成新字符,再插入到DOM里。这其中会出现的问题有:需要读取用户输入并和模型的数据结合,需要覆写用户的输入,需要手动管理整个更新过程,缺少丰富的表现形式。

AngularJS则不同,AngularJS编译器使用的是带指令的DOM,而不是字符串模板。它返回的是一个链接函数,这个函数和作用域模型结合就会生成一个动态视图。这个视图和模型的绑定过程是“透明的”。开发者不需要做任何关于更新视图的工作。并且应用没有用到innerHTML,所以我们也不用覆写用户的输入。更特别的是,Angular的指令不仅仅能使用字符串形式的绑定,还可以使用一些指示行为的结构体。

AngularJS的编译会生成一个“稳定的DOM”。这意味绑定了数据模型的DOM元素的实例不会在绑定的生命周期中发生改变。这也意味着代码中可以获取到DOM元素的实例引用并注册事件,不用担心这用引用会在模板和数据的结合时丢失。

Javascript 相关文章推荐
摘自百度的图片轮换效果代码
Nov 19 Javascript
javascript面向对象入门基础详细介绍
Sep 05 Javascript
js定时调用方法成功后并停止调用示例
Apr 08 Javascript
Internet Explorer 11 浏览器介绍:别叫我IE
Sep 28 Javascript
vue2的todolist入门小项目的详细解析
May 11 Javascript
vue.js 使用v-if v-else发现没有执行解决办法
May 15 Javascript
如何理解Vue的.sync修饰符的使用
Aug 17 Javascript
打通前后端构建一个Vue+Express的开发环境
Jul 17 Javascript
使用nvm和nrm优化node.js工作流的方法
Jan 17 Javascript
3分钟了解vue数据劫持的原理实现
May 01 Javascript
你或许不知道的一些npm实用技巧
Jul 04 Javascript
javascript简单实现深浅拷贝过程详解
Oct 08 Javascript
AngularJS初始化过程分析(引导程序)
Dec 06 #Javascript
什么是 AngularJS?AngularJS简介
Dec 06 #Javascript
AngularJS入门教程(二):AngularJS模板
Dec 06 #Javascript
AngularJS入门教程(一):静态模板
Dec 06 #Javascript
AngularJS入门教程(零):引导程序
Dec 06 #Javascript
AngularJS入门教程之学习环境搭建
Dec 06 #Javascript
AngularJS入门教程之Hello World!
Dec 06 #Javascript
You might like
php将字符串全部转换成大写或者小写的方法
2015/03/17 PHP
php字符串函数 str类常见用法示例
2020/05/15 PHP
强制设为首页代码
2006/06/19 Javascript
JavaScript中的其他对象
2008/01/16 Javascript
Jquery中children与find之间的区别详细解析
2013/11/29 Javascript
jquery实现向下滑出的二级导航下滑菜单效果
2015/08/25 Javascript
JS实现浏览器状态栏显示时间的方法
2015/10/27 Javascript
详解javascript遍历方式
2015/11/11 Javascript
基于gulp合并压缩Seajs模块的方式说明
2016/06/14 Javascript
Bootstrap树形菜单插件TreeView.js使用方法详解
2016/11/01 Javascript
JS中用try catch对代码运行的性能影响分析
2016/12/26 Javascript
BootStrap 弹出层代码
2017/02/09 Javascript
AngularJS路由切换实现方法分析
2017/03/17 Javascript
jQuery Validate格式验证功能实例代码(包括重名验证)
2017/07/18 jQuery
全面解析jQuery中的$(window)与$(document)的用法区别
2017/08/15 jQuery
解决node修改后需频繁手动重启的问题
2018/05/13 Javascript
js数组去重的N种方法(小结)
2018/06/07 Javascript
jQuery 筛选器简单操作示例
2019/10/02 jQuery
Python实现的金山快盘的签到程序
2013/01/17 Python
详解python调度框架APScheduler使用
2017/03/28 Python
Python实现字符串的逆序 C++字符串逆序算法
2020/05/28 Python
python字典值排序并取出前n个key值的方法
2018/10/17 Python
Python+OpenCV图片局部区域像素值处理改进版详解
2019/01/23 Python
使用python实现滑动验证码功能
2019/08/05 Python
python爬虫爬取幽默笑话网站
2019/10/24 Python
Python matplotlib图例放在外侧保存时显示不完整问题解决
2020/07/28 Python
Python+unittest+requests+excel实现接口自动化测试框架
2020/12/23 Python
GAP美国官网:美国休闲时尚品牌
2016/08/26 全球购物
绿色美容,有机护肤品和化妆品:Safe & Chic
2018/10/29 全球购物
加拿大专业美发产品购物网站:Chatters
2021/02/28 全球购物
浙大网新C/C++面试解惑
2015/05/27 面试题
如何提高MySql的安全性
2014/06/19 面试题
中学生家长评语大全
2014/04/16 职场文书
2014年度个人工作总结
2014/11/07 职场文书
公司2015年终工作总结
2015/05/26 职场文书
厉害!这是Redis可视化工具最全的横向评测
2021/07/15 Redis