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型的数据结构进行双向绑定时,不太理想,性能消耗太大。

加油!

时间: 2024-11-03 21:29:23

angular核心原理解析3:指令的执行过程的相关文章

angular核心原理解析1:angular自启动过程

angularJS的源代码整体上来说是一个自执行函数,在angularJS加载完成后,就会自动执行了. angular源代码中: angular = window.angular || (window.angular = {}) 定义一个全局的angular空对象. 然后: bindJQuery(); //绑定jQuery publishExternalAPI(angular); //扩展angular对象的方法和属性 jqLite(document).ready(function() { an

angular核心原理解析2:注入器的创建和使用

上一课没有讲到创建注入器的方法createInjector. 此方法,会创建两种不同的注入器:第一种叫做providerInjector,第二种叫做instanceInjector.providerInjector是用来创建provider的,instanceInjector是用来创建一个对象实例的. 我们可以在js代码中直接使用注入器: var myModule = angular.module("myModule", []); myModule.factory("pers

Promise核心原理解析

作者: HerryLo 本文永久有效链接: https://github.com/AttemptWeb...... Promises对象被用于表示一个异步操作的最终完成 (或失败), 及其结果值.主要是为了解决异步操作的问题. #Promise对象的状态 一个 Promise对象有以下三种状态: pending: 初始状态,既不是成功,也不是失败状态. fulfilled(resolved): 意味着操作成功完成. rejected: 意味着操作失败. Promise对象内部运行的一个变化, 变

GeoHash核心原理解析 - OPEN 开发经验库

阅读目录 引子 一.感性认识GeoHash 二.GeoHash算法的步骤 三.GeoHash Base32编码长度与精度 三.GeoHash算法 四.使用注意点 引子 机机是个好动又好学的孩子,平日里就喜欢拿着手机地图点点按按来查询一些好玩的东西.某一天机机到北海公园游玩,肚肚饿了,于是乎打开手机地图,搜索北海公园附近的餐馆,并选了其中一家用餐. 饭饱之后机机开始反思了,地图后台如何根据自己所在位置查询来查询附近餐馆的呢?苦思冥想了半天,机机想出了个方法:计算所在位置P与北京所有餐馆 的距离,然

GeoHash核心原理解析

引子 机机是个好动又好学的孩子,平日里就喜欢拿着手机地图点点按按来查询一些好玩的东西.某一天机机到北海公园游玩,肚肚饿了,于是乎打开手机地图,搜索北海公园附近的餐馆,并选了其中一家用餐. 饭饱之后机机开始反思了,地图后台如何根据自己所在位置查询来查询附近餐馆的呢?苦思冥想了半天,机机想出了个方法:计算所在位置P与北京所有餐馆的距离,然后返回距离<=1000米的餐馆.小得意了一会儿,机机发现北京的餐馆何其多啊,这样计算不得了,于是想了,既然知道经纬度了,那它应该知道自己在西城区,那应该计算所在位置

angualar入门学习-- 自定义指令 指令编译执行过程

3个阶段: 一.加载阶段 加载angular.js的源码,找到ng-app确定应用边界范围. 二.编译阶段 compile 查找所有指令,保存在一个列表中 对所有指令按优先级(property属性值)排序,根据指令的配置参数(template.transclude等)转换为DOM,使指令初具形态. 三.链接阶段 link 执行合体后的link函数.link一般用来操作DOM.绑定事件监听. 为每条指令运行link函数,即将view和scope链接起来,数据绑定:通过在数据上注册监听器来动态修改s

GeoHash原理解析

GeoHash 核心原理解析       引子 一提到索引,大家脑子里马上浮现出B树索引,因为大量的数据库(如MySQL.oracle.PostgreSQL等)都在使用B树.B树索引本质上是对索引字段进行排序,然后通过类似二分查找的方法进行快速查找,即它要求索引的字段是可排序的,一般而言,可排序的是一维字段,比如时间.年龄.薪水等等.但是对于空间上的一个点(二维,包括经度和纬度),如何排序呢?又如何索引呢?解决的方法很多,下文介绍一种方法来解决这一问题.   思想:如果能通过某种方法将二维的点数

Web API之过滤器执行过程原理解析【二】(十一)

前言 上一节我们详细讲解了过滤器的创建过程以及粗略的介绍了五种过滤器,用此五种过滤器对实现对执行Action方法各个时期的拦截非常重要.这一节我们简单将讲述在Action方法上.控制器上.全局上以及授权上的自定义特性的执行过程. APiController 之前有讲到该APiController,也就稍微介绍了,这节我们来详细此Web API控制器的基类: 1 public abstract class ApiController : IHttpController, IDisposable 2

深入解析Koa之核心原理

这篇文章主要介绍了玩转Koa之核心原理分析,本文从封装创建应用程序函数.扩展res和req.中间件实现原理.异常处理的等这几个方面来介绍,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下.如有不足之处,欢迎批评指正. Koa作为下一代Web开发框架,不仅让我们体验到了async/await语法带来同步方式书写异步代码的酸爽,而且本身简洁的特点,更加利于开发者结合业务本身进行扩展. 本文从以下几个方面解读Koa源码: 封装创建应用程序函数 扩展res和req 中间件实现原理