AngularJS Directive 学习笔记

指令 Directive

指令要点

大漠老师的教学节点

  • 解析最简单的指令 hello: 匹配模式 restrict
  • 解析最简单的指令 hello: templatetempmlateUrl$templateCache
  • 解析最简单的指令 hello: replacetransclude
  • compilelink (操作元素、添加 CSS 样式、绑定事件)
  • 指令与控制器之间的交互
  • 指令间的交互
  • scope 的类型与独立 scope
  • scope 的绑定策略

简单的指令

app.directive('hello', function() {
    return {

        // 四种: Element, Attribute, Comment, Class
        // Default: Attribute
        // Comment: <!-- directive:hello -->
        restrict: "E/A/M/C",

        // 模板
        template: '<h1>Hi everyone! </h1>',
        templateUrl: 'temp.html',

        // 是否替换节点内的内容
        replace: true
    }
});

transculde 转置

transclude 作用在于转置指令内部原有的内容,以免 replace: true 被设置时内部内容被全部替换,这样非常有用于嵌套指令

app.directive('ele', function() {
    return {

        // 注意:不能用 replace: true
        restrict: 'AE',
        transclude: true,

        // 标签内部内容将会被转置到 div[ng-transclude] 内部
        template: "<h1>Hello AngularJS!</h1><div ng-transclude></div>"
    }
});

模板缓存

  • run 方法会在注册器加载完所有模块之后被执行一次

  • $templateCache 可以缓存模板以供多个指令使用

  • put & get 类似面向对象的 setter & getter 方法

app.run(function($templateCache) {
    $templateCache.put('hello.html', '<div>Hello AngularJS!</div>');
});

// use get method to get cache
app.directive('ele', function($templateCache) {
    return {
        template: $templateCache.get('hello.html')
    }
});
  • 加载阶段

    • 加载 angular.js,找到 ng-app 指令,确定应用的边界
  • 编译阶段

    • 遍历 DOM,找到所有指令
    • 根据指令代码中的 templatereplacetransclude 转换 DOM 结构
    • 如果存在 compile 函数则调用
  • 链接阶段

    • 对每一条指令运行 link 函数
    • link 函数一般用来操作 DOM、绑定事件监听器

HTML 代码

<loader howToLoad="loadData()">Hover to load</loader>
<loader howToLoad="loadData2()">Hover to load</loader>

AngularJS 代码

myModule.controller('MyCtrl', ['$scope',
    function($scope) {
        $scope.loadData = function() {
            console.log('Loading...');
        };

        $scope.loadData2 = function() {
            console.log('Loading2...');
        }
    }
]);

myModule.directive('loader', function() {
    return {
        resetrict: 'AE',
        template: '',
        replace: true,
        link: function(scope, element, attr) {

            // 绑定事件
            element.bind('mouseenter', function() {

                // 以下两种形式都可以,推荐下面的
                scope.loadData();
                scope.$apply('loadData()');

                // 获取属性值
                // 根据指令特定属性的不同应用不同方法
                // 方法应小写
                scope.$apply(attrs.howtoload);
            });
        }
    }
});

指令之间的交互

重点是创建独立 scope,使得指令之间不互相影响

HTML 代码

<superman strength>Strength</superman>
<superman strength speed>Strength &amp; Speed</superman>
<superman strength speed light>Stength &amp; Speed &amp; Light</superman>

AngularJS 代码

myModule.directive('superman', function() {
    return {

        // 创建独立 scope
        scope: {},
        restrict: 'AE',

        // 希望指令暴露出一些方法编写在 controller 里面供其他指令调用
        // 同时使用 this 指代 $scope,这样交互的指令才能引用
        controller: function($scope) {
            $scope.abilities = [];
            this.addStrength = function () {
                $scope.abilities.push('Strength');
            };
            this.addSpeed = function () {
                $scope.abilities.push('Speed');
            };
            this.addLight = function () {
                $scope.abilities.push('Light');
            };
        },

        // link 处理指令内部事件
        link: function (scope, element, attrs) {
            element.addClass('btn btn-primary btn-lg');
            element.bind('mouseenter', function() {
                console.log(scope.abilities);
            });
        }
    };
});

myModule.directive('strength', function() {
    return {

        // 依赖于 superman 指令,这样 link 函数才可以调用 supermanCtrl 参数
        require: '^superman',
        link: function(scope, element, attrs, supermanCtrl) {
            supermanCtrl.addStrength();
        }
    };
});

myModule.directive('speed', function() {
    return {
        require: '^superman',
        link: function(scope, element, attrs, supermanCtrl) {
            supermanCtrl.addSpeed();
        }
    };
});

myModule.directive('light', function() {
    return {
        require: '^superman',
        link: function(scope, element, attrs, supermanCtrl) {
            supermanCtrl.addLight();
        }
    };
});
原文地址:https://www.cnblogs.com/youngdze/p/4028032.html