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 被設置時內部內容被所有替換,這樣很是有用於嵌套指令javascript

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

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

        // 標籤內部內容將會被轉置到 div[ng-transclude] 內部
        template: "<h1>Hello AngularJS!</h1><div ng-transclude></div>"
    }
});

模板緩存

  • run 方法會在註冊器加載完全部模塊以後被執行一次html

  • $templateCache 能夠緩存模板以供多個指令使用java

  • put & get 相似面向對象的 setter & getter 方法angularjs

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 指令,肯定應用的邊界
  • 編譯階段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,使得指令之間不互相影響ui

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();
        }
    };
});
相關文章
相關標籤/搜索