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 相关文章推荐
浅谈tudou土豆网首页图片延迟加载的效果
Jun 23 Javascript
jquery nth-child()选择器的简单应用
Jul 10 Javascript
原生Ajax 和jQuery Ajax的区别示例分析
Dec 17 Javascript
JavaScript实现点击按钮字体放大、缩小
Feb 29 Javascript
JS实现控制文本框的内容
Jul 10 Javascript
深入理解AngularJS中的ng-bind-html指令和$sce服务
Sep 08 Javascript
JS针对Array的各种操作汇总
Nov 29 Javascript
axios发送post请求,提交图片类型表单数据方法
Mar 16 Javascript
Vue中的v-for指令不起效果的解决方法
Sep 27 Javascript
layui switch 开关监听 弹出确定状态转换的例子
Sep 21 Javascript
JS如何在数组指定位置插入元素
Mar 10 Javascript
微信小程序swiper组件实现抖音翻页切换视频功能的实例代码
Jun 24 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中的字符串函数
2006/10/09 PHP
laravel 修改记住我功能的cookie保存时间的方法
2019/10/14 PHP
jQuery 页面载入进度条实现代码
2009/02/08 Javascript
javascript标签在页面中的位置探讨
2013/04/11 Javascript
使用JavaScript 编写简单计算器
2014/11/24 Javascript
jQuery学习笔记之Ajax用法实例详解
2015/12/01 Javascript
jQuery中delegate()方法的用法详解
2016/10/13 Javascript
快速实现jQuery多级菜单效果
2017/02/01 Javascript
微信小程序开发之麦克风动画 帧动画 放大 淡出
2017/04/18 Javascript
详解Vue组件实现tips的总结
2017/11/01 Javascript
AjaxUpLoad.js实现文件上传
2018/03/05 Javascript
Vue axios设置访问基础路径方法
2018/09/19 Javascript
详解es6新增数组方法简便了哪些操作
2019/05/09 Javascript
微信小程序自定义组件实现环形进度条
2020/11/17 Javascript
详解element-ui级联菜单(城市三级联动菜单)和回显问题
2019/10/02 Javascript
VUE+elementui组件在table-cell单元格中绘制微型echarts图
2020/04/20 Javascript
[04:16]完美世界DOTA2联赛PWL S2 集锦第一期
2020/11/23 DOTA
[01:18:35]DOTA2-DPC中国联赛 正赛 Elephant vs LBZS BO3 第一场 1月29日
2021/03/11 DOTA
python更新列表的方法
2015/07/28 Python
深入理解Python中字典的键的使用
2015/08/19 Python
Python切片操作实例分析
2018/03/16 Python
python切片(获取一个子列表(数组))详解
2019/08/09 Python
python协程gevent案例 爬取斗鱼图片过程解析
2019/08/27 Python
使用TensorFlow-Slim进行图像分类的实现
2019/12/31 Python
使用python 的matplotlib 画轨道实例
2020/01/19 Python
TensorFlow实现checkpoint文件转换为pb文件
2020/02/10 Python
Pycharm如何运行.py文件的方法步骤
2020/03/03 Python
Pycharm导入anaconda环境的教程图解
2020/07/31 Python
HTML文本属性&amp;颜色控制属性的实现
2019/12/17 HTML / CSS
Giglio英国站:意大利奢侈品购物网
2018/03/06 全球购物
Ray-Ban雷朋瑞典官方网站:全球领先的太阳眼镜品牌
2019/08/22 全球购物
运动会跳远广播稿
2014/02/04 职场文书
俄语专业职业生涯规划
2014/02/26 职场文书
西双版纳导游词
2015/02/03 职场文书
Pytorch 如何加速Dataloader提升数据读取速度
2021/05/28 Python
这样写python注释让代码更加的优雅
2021/06/02 Python