angular核心原理解析3:指令的执行过程
指令的执行过程分析。
我们知道指令的执行分两个阶段,一个是compile,一个是link。
我们可以在指令中自定义compile和link。
首先,我们来讲解如何自定义link函数
举个例子:
<!doctype html>
<html ng-app="myModule">
<head>
</head>
<body>
<hello></hello>
</body>
<script src="angular.js"></script>
<script src="helloAngular.js"></script>
</html>
helloAngular.js代码
var myModule = angular.module("myModule", []);
myModule.directive("hello", function(){
return {
restrict: "E",
template: "<div>Hello,Angular</div>",
replace: true,
link: function(scope, el, attrs, controller){
el.on("click", function(){
alert("鼠标点击");
});
}
}
});
link方法一般用来对元素进行处理。这里是对元素进行事件的绑定。当用户元素div进行点击时,会弹出鼠标点击的框。
然后,我们来讲解如何自定义compile函数
<!doctype html>
<html ng-app="myModule">
<head>
</head>
<body>
<div hellos="3">
<p>hello,Angular!</p>
</div>
</body>
<script src="angular.js"></script>
<script src="helloAngular.js"></script>
</html>
helloAngular.js代码
var myModule = angular.module("myModule", []);
myModule.directive("hellos", function(){
return {
restrict: "A",
compile: function(el, attrs, transclude){
alert("指令编译");
var tpl = el.children().clone(); //p标签以及内容
for(var i =0;i<attrs.hellos -1;i++){
el.append(tpl.clone());
}
return function(scope, el, attrs, controller){ //compile必须要return这样的一个函数,这个函数其实就是link函数,在链接阶段,就会执行此link函数。
alert("指令链接");
}
}
}
});
当页面加载进来后,就会弹出指令编译,然后再弹出指令链接的框。
如果,我们在上面的helloAngular.js中,不仅自定义了compile方法,而且也自定义了link方法。比如:
var myModule = angular.module("myModule", []);
myModule.directive("hellos", function(){ //定义一个hellos指令
return {
restrict: "A",
compile: function(el, attrs, transclude){
alert("指令编译");
var tpl = el.children().clone(); //p标签以及内容
for(var i =0;i<attrs.hellos -1;i++){
el.append(tpl.clone());
}
return function(scope, el, attrs, controller){ //compile必须要return这样的一个函数,这个函数其实就是link函数,在链接阶段,就会执行此link函数。
alert("指令链接");
}
}
link : function(scope, el, attrs, controller){
alert("自定义的link");
}
}
});
当页面加载进来时,自定义的link不会弹出来。意思就是说,当存在compile时,不会执行你自定义的link函数,因为angular会把compile返回的函数当做link函数来执行。当不存在compile时,就会执行你自定义的link函数。
compile函数很少被用到,写起来比较麻烦。
compile函数的作用是对指令的模板进行转换,比如,上面的例子中,compile函数就把指令的模板进行了叠加,改变了页面上的DOM结构。
link函数的作用是在模型和视图之间建立关联,同时在元素上绑定事件监听。
scope在链接阶段才会被绑定到元素上,因此在compile中操作scope会报错。
对于同一个指令的多个实例,compile只会执行一次,而link对于指令的每个实例都会执行一次。比如:ng-repeat指令,如果元素的ng-repeat=3,那么ng-repeat指令的compile只会执行一次,而link会执行三次。
对于指令,我们一般只需要自定义link函数就行了。
接下来,我们来讲解使用compile服务,在页面上查找指令并编译指令的过程:
从ng-app开始,递归子层的DOM结构,收集指令,然后在ng-app指令的位置创建$rootScope作用域。比如:上面的代码中,我们注册了一个hellos指令,angular在启动时,就会遍历DOM去查找这个指令。
如果有需要,会为指令生成childScope。
调用每个指令自己的compile函数,生成自己的compositeLinkFn函数。
编译的结果是返回一个publicLinkFn函数。
编译完成之后立即调用生成的publicLinkFn函数。
angular对tree型的数据结构进行双向绑定时,不太理想,性能消耗太大。
加油!
angular核心原理解析3:指令的执行过程的更多相关文章
- angular核心原理解析1:angular自启动过程
angularJS的源代码整体上来说是一个自执行函数,在angularJS加载完成后,就会自动执行了. angular源代码中: angular = window.angular || (window ...
- angular核心原理解析2:注入器的创建和使用
上一课没有讲到创建注入器的方法createInjector. 此方法,会创建两种不同的注入器:第一种叫做providerInjector,第二种叫做instanceInjector.providerI ...
- 【算法】(查找你附近的人) GeoHash核心原理解析及代码实现
本文地址 原文地址 分享提纲: 0. 引子 1. 感性认识GeoHash 2. GeoHash算法的步骤 3. GeoHash Base32编码长度与精度 4. GeoHash算法 5. 使用注意点( ...
- Java并发包JUC核心原理解析
CS-LogN思维导图:记录CS基础 面试题 开源地址:https://github.com/FISHers6/CS-LogN JUC 分类 线程管理 线程池相关类 Executor.Executor ...
- ibatis 核心原理解析!
关注下方公众号,可以在公众号后台回复“博客园”,免费获得作者 Java 知识体系/面试必看资料. 最近查找一个生产问题的原因,需要深入研究 ibatis 框架的源码.虽然最后证明问题的原因与 ibat ...
- ibatis 核心原理解析
最近查找一个生产问题的原因,需要深入研究 ibatis 框架的源码.虽然最后证明问题的原因与 ibatis 无关,但是这个过程加深了对 ibatis 框架原理的理解. 这篇文章主要就来讲讲 ibati ...
- Promise核心原理解析
作者: HerryLo 本文永久有效链接: https://github.com/AttemptWeb...... Promises对象被用于表示一个异步操作的最终完成 (或失败), 及其结果值.主要 ...
- 「进阶篇」Vue Router 核心原理解析
前言 此篇为进阶篇,希望读者有 Vue.js,Vue Router 的使用经验,并对 Vue.js 核心原理有简单了解: 不会大篇幅手撕源码,会贴最核心的源码,对应的官方仓库源码地址会放到超上,可以配 ...
- NameServer 核心原理解析
在之前的文章中,已经把 Broker.Producer 和 Conusmer 的部分源码和核心的机制介绍的差不多了,但是其实 RocketMQ 中还有一个比较关键但是我们平时很容易忽略的组件--Nam ...
随机推荐
- XML解析的二种方法之Sax解析
package com.huawei.xml; import java.io.InputStream;import java.util.Stack; import javax.xml.parsers. ...
- css常用属性总结:颜色和单位
在css代码编写中,估计颜色和单位是必不可少的,然而在css中关于颜色和单位值的写法有很多种写法,所以有必要把它弄清楚. 颜色 当初我在初学前端的时候,就会冒出一个疑问“我该如何设置网页颜色?”,一般 ...
- centos7 安装 openvswitch
1.安装依赖包: yum -y install make gcc openssl-devel autoconf automake rpm-build redhat-rpm-config yum - ...
- springMVC入门程序。使用springmvc实现商品列表的展示。
1.1 开发环境 本教程使用环境: Jdk:jdk1.7.0_72 Eclipse:mars Tomcat:apache-tomcat-7.0.53 Springmvc:4.1.3 1.2 需求 使用 ...
- 使用mybatis提供的各种标签方法实现动态拼接Sql。使用foreach标签实现遍历查询。比如实现select * from user where id in(1,10,24)这条sql查询语句。
向sql传递数组或List,mybatis使用foreach解析,如下: 需求: 传入多个id查询用户信息,用下边的sql实现: select * from user where id in(1,10 ...
- 在Qt(C++)中使用QThread实现多线程
1. 引言 多线程对于需要处理耗时任务的应用很有用,一方面响应用户操作.更新界面显示,另一方面在"后台"进行耗时操作,比如大量运算.复制大文件.网络传输等. 使用Qt框架开发应用程 ...
- 前端基础之:JQuery(可编辑版)
前端基础之jquery 一 jQuery是什么? [1] jQuery由美国人John Resig创建,至今已吸引了来自世界各地的众多 javascript高手加入其team. [2] ...
- Android 实现在Activity中操作刷新另外一个Activity数据列表
做android项目中遇到这样一个问题:有两个acticity,一个显示好友列表,另外一个显示会话列表,现在问题是在会话界面增加一个添加好友功能,添加好友后要求实时的刷新好友列表. 想了想,找了两种方 ...
- AspNet.WebAPI.OData.ODataPQ实现WebAPI的分页查询服务-(个人拙笔)(转)
出处:http://www.bubuko.com/infodetail-827612.html AspNet.WebAPI.OData.ODataPQ 这是针对 Asp.net WebAPI ODat ...
- linux平台使用spark-submit以cluster模式提交spark应用到standalone集群
shell脚本如下 sparkHome=/home/spark/spark-2.2.0-bin-hadoop2.7 $sparkHome/bin/spark-submit \ --class stre ...