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

    加油!

  • 相关阅读:
    洞察僵尸网络的4条关键线索,你知道吗?
    数据即服务(DaaS)的好处和趋势
    AIOT:什么是智联网,它是未来吗?
    渐变略过效果
    页面头部banner动画效果
    小三角
    监测屏幕宽度
    开关效果
    高级轮播
    手机端跳转页面指定楼层
  • 原文地址:https://www.cnblogs.com/chaojidan/p/4282512.html
Copyright © 2011-2022 走看看