OurJS


OurJS-我们的JS, 我们的技术-IT文摘; 专注JS相关领域;
我们热爱编程, 我们热爱技术;我们是高大上, 有品味的码农;

欢迎您订阅我们的技术周刊


我们会向您分享我们精心收集整理的,最新的行业资讯,技术动态,外文翻译,热点文章;
我们使用第三方邮件列表向您推送,我们不保存您的任何个人资料,注重您的隐私,您可以随时退订,

欢迎分享您的观点,经验,技巧,心得

让我们一起找寻程序员的快乐,探索技术, 发现IT人生的乐趣;


本网站使用缓存技术每次加载仅需很小流量, 可在手机中流畅浏览;
如果您发现任何BUG,请即时告知我们: ourjs(at)ourjs.com

AngularJS的启动引导过程


分享到


分类 大话编程   关键字 分享   发布 2596887568  1429170052243
注意 转载须保留原文链接,译文链接,作者译者等信息。  

目录:

  1. 引导之前
  2. 自动引导启动框架
  3. 手工引导启动框架
  4. 引导第1步:创建注入器
  5. 引导第2步:创建根作用域
  6. 引导第3步:编译DOM子树
  7. 编译器/$compile
  8. 指令/directive
  9. 指令的规范化

1.引导之前:库阶段

在示例中,我们定义了一个指令ez-duang, 它应该会展开成一个动画 显示出来。 AngularJS代码:

   angular.module("ezstuff",[])
   .directive("ezDuang",function(){
           return {
               restrict : "E",
               template : "<img src='http://ww4.sinaimg.cn/bmiddle/757eb2ffjw1eptcr4qobjg209205dthh.gif'>"
           };
   });

html代码:

  • 应该在下面看到一幅动画才对!

但是,看起来没有什么动画显示出来。AngularJS似乎没有工作,为什么?

有点像操作系统,AngularJs也有一个启动引导的概念。

当你在HTML文件中引入angular.min.js时,AngularJS只是建立了一个全局的 angular对象,这个对象有一些方法可供开发者调用,但应用的框架还没有建立。

在这个阶段,AngularJS还只是一个库,和jQuery类似,你可以使用angular.element() 操作DOM,也可以使用angular.injector()创建注入器... 但是,你定义的指令,你 创建的控制器,你封装的服务,你开发的模板...所有这些组件,还静静地躺在那里, 没有被整合在一起。

我们说,框架还没有运转起来,现在还是库阶段。

只有通过启动引导,AngularJS框架才开始将那些组件拼接在一起,应用才真正 开始运转。

像下面这样,试着给html元素增加一个ng-app指令,再重新运行!

 <html ng-app="ezstuff">
    ....
    </html>

2.自动引导启动框架

就像你看到的那样,如果HTML模板中有某个标签有ng-app属性,那么当DOM树建立成功后, AngularJS就会自动进入引导过程,启动整个框架:

111png

试着把ng-app指令挪到body元素上,看看有什么不同?

3.手工引导启动框架

在大多数情况下,我们都使用ng-app指令来进行自动引导启动,但是如果一个HTML文件中 有多个ng-app,AngularJS只会自动引导启动它找到的第一个ng-app应用,这是需要手工引导 的一个应用场景。

我们可以利用 angular.bootstrap() 方法进行手动引导:

angular.bootstrap(element, [modules], [config]);

bootstrap方法有三个参数:

element : 一个DOM元素,以这个元素为Angular应用的根,等同自动引导时ng-app所在 的元素。这个参数是必须的。比如:document、document.body等。modules : 引导时需要载入的模块数组。比如:[]、["ezstuff"]等。由于我们的HTML中引用 了ezstuff模块中定义的ez-duang指令,所以,我们需要指定载入ezstuff模块。config :引导配置项,可选。我们先忽略。 最终,我们使用如下的形式进行手动引导:

angular.bootstrap(document,["ezstuff"]); 改进的代码已经预置于在线课程。请点击【手动引导】按钮启动引导过程!

4.引导第1步:创建注入器

引导过程使AngularJS从库转变成了一个框架。

回忆我们之前提到,AngularJS深入骨髓地使用着依赖注入,那么,在引导过程 之初,首先需要创建一个注入器就毫不奇怪了。

注入器是通向AngularJS所有功能的入口,而AngularJS的功能实现,是通过模块的方式组织的。所以, 在创建注入器的时候,需要告诉AngularJS载入哪些模块(ng模块是内置载入的,不需要显式指定)。

0022png

在自动启动引导的场景下,可以给ng-app赋值以指定一个需要载入的模块,比如: ng-app = "ezstuff"

在手动启动引导的场景下,通过bootstrap方法的第二个参数指定需要载入的模块,比如: angular.bootstrap(document,["ezstuff"]);

INSIDE:无论自动启动还是手工启动,最终都是调用angular对象上的injector()方法创建了一个 注入器,然后把这个注入器存入了根对象的data里: var injector = angular.injector(["ng","ezstuff"]); angular.element(document).data("$injector",injector);

我们在在线课程的代码中,开始模拟引导启动过程的第一步:创建注入器。

5.引导第2步:创建根作用域

scope对象是AngularJS实现数据绑定的重要服务,所以,在引导启动建立了注入器之后, AngularJS马上在应用的根节点上创建一个根作用域:$rootScope对象。

0033png

如果是自动引导启动,那么ng-app所在的DOM节点对应着根作用域。如果是手工引导启动, 那么在bootstrap方法中指定的第一个参数就对应着根作用域。

无论哪一种情况,一旦$rootScope对象创建成功,AngularJS就将这个对象存储到根节点 的data中,我们可以使用如下的方法查看这个对象: angular.element(approot).data("$rootScope");

你可以摆弄一下代码,看看$rootScope到底是什么东西。

6.引导第3步:编译DOM子树

引导过程的最后一步,是以ng-app所在DOM节点为根节点,对这棵DOM子树进行编译。

0044png

编译过程通常借助于指令,完成这几种操作:

  1. 对DOM对象进行变换。
  2. 在DOM对象上挂接事件监听。
  3. 在DOM对象对应的scope对象上挂接数据监听。 编译过程是AngularJS相当有特点的一个存在,我们将在下一节继续深入。

现在你应该看到结果了吧?

7.编译器/$compile

编译器$compile是一个AngularJS的内置服务,它负责遍历DOM树来查找匹配指令, 并调用指令的实现代码进行处理。

HTML编译包括3个步骤:

匹配指令 $compile遍历DOM树,如果发现有元素匹配了某个指令,那么这个指令将被加入 该DOM元素的指令列表中。一个DOM元素可能匹配多个指令。

执行指令的编译函数 当一个DOM元素的所有指令都找齐后,编译器根据指令的优先级/priority指令进行排序。 每个指令的compile函数被依次执行。每个compile执行的结果产生一个link函数,这些 link函数合并成一个复合link函数。

执行生成的链接函数 $compile通过执行指令的link函数,将模板和scope链接起来。结果就是一个DOM视图和scope对象模型 之间的动态数据绑定。

为何将编译和连接两个步骤分开?

简单说,当数据模型的变化会导致DOM结构变化时,指令就需要分别定义compile()函数和link函数。 例如,ng-repeat指令需要为数据集合中的每个成员复制DOM元素。将编译和链接过程分开可以有效 地提高性能,因为DOM的复制放在compile()里,仅需要执行一次,但链接则发生在每个生成的DOM元素 上,所以指令的link()函数会执行多次。

指令很少需要compile函数,因为大多数指令考虑的是作用于特定的DOM元素实例,而不是改变DOM 的结构。所以link函数更常用。

8.指令/directive

笼统地说,指令是DOM元素(例如属性、元素、CSS类等)上的标记符,用来告诉AngularJS的HTML编译器 ($compile服务)将特定的行为绑定到DOM元素,或者改变DOM元素。

指令可以放置在元素名、属性、CSS类名称及备注中。下面是一些等效的触发"ng-bind"指令的写法:

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

指令的实现本质上就是一个类工厂,它返回一个指令定义对象,编译器根据这个指令定义对象进行操作。

0055png

问题是,HTML中的ez-duang,怎么就匹配到了JavaScript中的ezDuang?

9.指令的规范化

AngularJS在进行匹配检测之前,首先对HTML元素的标签和属性名转化成规范的驼峰式字符串:

  1. 去除名称前缀的x-和data-
  2. 以: , - 或 _ 为分割符,将字符串切分成单词,除第一个单词外,其余单词首字母大写
  3. 重新拼接各单词 例如,下面的写法都等效地匹配ngBind指令:

     <span ng-bind="name"></span> <br>
     <span ng:bind="name"></span> <br>
     <span ng_bind="name"></span> <br>
     <span data-ng-bind="name"></span> <br>
     <span x-ng-bind="name"></span> <br>

所以,在前面的课程中,我们在HTML中使用的ez-duang指令,将被规范为ezDuang, 编译器使用这个规范化的名称与注册的指令进行匹配。 参考资料:http://www.hubwiz.com/course/54f3ba65e564e50cfccbad4b/

原文地址: 点此
社区评论 ( Beta版 )
OnceDoc 您自己的企业内容管理系统——文档、流程、知识库、报表、网盘All In One

访问404页面,寻找丢失儿童
 热门文章 - 分享最多
  1. 将BootstrapJS和AngularJS结合使用以及为什么不用jQuery
  2. NativeScript的工作原理:用JavaScript调用原生API实现跨平台
  3. 6款基于Node.JS的开源内容管理和静态网站生成系统
  4. NativeScript的竞争者React Native:又一个用JavaScript写原生iOS应用的项目
  5. Session劫持与Session-ID的安全长度
  6. 2015年度开发者调查:JS最流行;ObjC工资最高;最想学Android
  7. 用原生HTML5控件实现输入框自动提示(下拉列表补全)功能
  8. 微软,IBM,ARM等大公司先后加入对Node.js/io.js的支持
  9. 使用Node.JS监听文件夹变化
  10. 编写高性能HTML网页应用
  11. 用 OnceAir 搭建个人Git/Svn/照片备份服务器,每年电费7块钱

 相关阅读 - 大话编程
  1. 史上最全的基于HTML5开源JavaScript游戏引擎列表
  2. Ruby和NodeJS结合使用:Async Server And Fiber
  3. 将BootstrapJS和AngularJS结合使用以及为什么不用jQuery
  4. Sortable极小的可拖放排序分组库;支持AngularJS,React,Meteor
  5. JavaScript中的$$(*)代表什么和$选择器的由来
  6. javaScript 依赖管理
  7. JavaScript代码组织结构良好的5个特点[reuqire.js]
  8. 怎样用纯HTML和CSS更改默认的上传文件按钮样式
  9. 今天我去面试, 受打击了:你是学 .net 的吧?
  10. JavaScript中的继承,构造函数以及new关键字的作用

 关键字 - 分享
  1. 树莓派4对比测试:性能提升3倍启动时间反而变慢?TF卡成最大瓶颈
  2. GO有语法缺陷,缺少泛型、public/private、三元运算符?我不喜欢 Go 语言的十个理由
  3. 不用花钱和推广,用户就能从这些渠道进入小程序!
  4. 微服务运维难维护?数据基础架构公司Segment宣布放弃微服务构架
  5. Node初学者入门,一本全面的NodeJS教程
  6. WordPress、百度宣布停止使用React(Native)开源项目,Facebook开源专利许可潜在的法律风险
  7. 一位自由职业者的分享:程序员怎样找兼职?
  8. 金木水火土五行属相婚配表
  9. 金木水火土五行相生相克年份查询表 
  10. Debian/Ubuntu Linux搭建SVN服务器,并设置开机默认启动

 欢迎订阅 - 技术周刊

我们热爱编程, 我们热爱技术; 我们是高端, 大气, 上档次, 有品味, 时刻需要和国际接轨的码农; 欢迎您订阅我们的技术周刊; 您只需要在右上角输入您的邮箱即可; 我们注重您的隐私,您可以随时退订.
加入我们吧! 让我们一起找寻码农的快乐,探索技术, 发现IT人生的乐趣;


 关注我们

我们的微信公众号: ourjs-com
打开微信扫一扫即可关注我们:
IT文摘-程序员(码农)技术周刊

ourjs官方微信号