• 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();
            }
        };
    });
    
  • 相关阅读:
    [LintCode] Single Number 单独的数字
    [LeetCode] 444. Sequence Reconstruction 序列重建
    [LeetCode] K-th Smallest in Lexicographical Order 字典顺序的第K小数字
    [LeetCode] Arranging Coins 排列硬币
    [LeetCode] Ternary Expression Parser 三元表达式解析器
    [LeetCode] 436. Find Right Interval 找右区间
    在Mac上配置全局的Git忽略文件
    Git『Everything up-to-date』问题解决
    Android组件化框架项目详解
    Android架构设计之插件化、组件化
  • 原文地址:https://www.cnblogs.com/youngdze/p/4028032.html
Copyright © 2020-2023  润新知