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 相关文章推荐
基于jQuery的让非HTML5浏览器支持placeholder属性的代码
May 24 Javascript
jquery动态加载图片数据练习代码
Aug 04 Javascript
JS实现文件动态顺序载入的方法
Mar 07 Javascript
JQUERY简单按钮轮换选中效果实现方法
May 07 Javascript
jquery实现可自动收缩的TAB网页选项卡代码
Sep 06 Javascript
jQuery拖动布局其结果保存到数据库
Oct 09 Javascript
微信小程序 swiper组件轮播图详解及实例
Nov 16 Javascript
谈谈jQuery之Deferred源码剖析
Dec 19 Javascript
JavaScript使用readAsDataURL读取图像文件
May 10 Javascript
利用Webpack实现小程序多项目管理的方法
Feb 25 Javascript
vue+element实现表格新增、编辑、删除功能
May 28 Javascript
基于jquery实现的tab选项卡功能示例【附源码下载】
Jun 10 jQuery
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
全国FM电台频率大全 - 12 安徽省
2020/03/11 无线电
[EPIC] Larva vs Flash ZvT @ Crossing Field [2017-10-09]
2020/03/17 星际争霸
写php分页时出现的Fatal error的解决方法
2011/04/18 PHP
PHP的微信支付接口使用方法讲解
2019/03/08 PHP
新手入门常用代码集锦
2007/01/11 Javascript
Prototype Hash对象 学习
2009/07/19 Javascript
jQuery 打造动态下滑菜单实现说明
2010/04/15 Javascript
基于jquery的Repeater实现代码
2010/07/17 Javascript
js解析与序列化json数据(二)序列化探讨
2013/02/01 Javascript
纯js实现仿QQ邮箱弹出确认框
2015/04/29 Javascript
基于jQuery插件实现环形图标菜单旋转切换特效
2015/05/15 Javascript
简单分析javascript面向对象与原型
2015/05/21 Javascript
基于JQuery实现图片轮播效果(焦点图)
2016/02/02 Javascript
谈一谈js中的执行环境及作用域
2016/03/30 Javascript
详解JavaScript中Hash Map映射结构的实现
2016/05/21 Javascript
实现一个简单的vue无限加载指令方法
2017/01/10 Javascript
js实现贪吃蛇小游戏(容易理解)
2017/01/22 Javascript
jQuery表单验证之密码确认
2017/05/22 jQuery
Angular 4依赖注入学习教程之简介(一)
2017/06/04 Javascript
微信小程序支付及退款流程详解
2017/11/30 Javascript
Vue.js 父子组件通信的十种方式
2018/10/30 Javascript
深入浅析Vue 中 ref 的使用
2019/04/29 Javascript
[53:21]2014 DOTA2国际邀请赛中国区预选赛5.21 DT VS LGD-CDEC
2014/05/22 DOTA
[01:20:47]DOTA2-DPC中国联赛 正赛 Ehome vs Magma BO3 第一场 1月19日
2021/03/11 DOTA
以Flask为例讲解Python的框架的使用方法
2015/04/29 Python
pytorch点乘与叉乘示例讲解
2019/12/27 Python
Marmot土拨鼠官网:美国专业户外运动品牌
2018/01/11 全球购物
马来西亚综合购物网站:Lazada马来西亚
2018/06/05 全球购物
广州品高软件.net笔面试题目
2012/04/18 面试题
2014年小学元旦活动方案
2014/02/12 职场文书
学历公证委托书
2014/04/09 职场文书
婚前财产协议书范本
2014/10/19 职场文书
硕士学位论文评语
2014/12/31 职场文书
2015年光棍节活动总结
2015/03/24 职场文书
Django项目配置Memcached和Redis, 缓存选择哪个更有优势
2021/04/06 Python
彩虹社八名人气艺人全新周边限时推出,性转女装男装一次拥有!
2022/04/01 日漫