AngularJS进修笔记(2) --- 指令参数和scope绑定战略

弁言

指令(Directive)能够说是 AngularJS 的中心,而其开辟也是比较难题的,本文重要引见指令的一些参数和scope的绑定战略。

参数

从 AngularJS 的官方文档中看到指令的参数以下:

{
    priority: 0,
    template: '<div></div>', // or // function(tElement, tAttrs) { ... },
    // or
    // templateUrl: 'directive.html', // or // function(tElement, tAttrs) { ... },
    transclude: false,
    restrict: 'A',
    scope: false,
    controller: function($scope, $element, $attrs, $transclude, otherInjectables) { ... },
    controllerAs: 'stringAlias',
    require: 'siblingDirectiveName', // or // ['^parentDirectiveName', '?optionalDirectiveName', '?^optionalParent'],
    compile: function compile(tElement, tAttrs, transclude) {
      return {
        pre: function preLink(scope, iElement, iAttrs, controller) { ... },
        post: function postLink(scope, iElement, iAttrs, controller) { ... }
      }
      // or
      // return function postLink( ... ) { ... }
    },
    // or
    // link: {
    //  pre: function preLink(scope, iElement, iAttrs, controller) { ... },
    //  post: function postLink(scope, iElement, iAttrs, controller) { ... }
    // }
    // or
    // link: function postLink( ... ) { ... }
}

下面细致解说每一个参数。

priority(Number)

指令实行的优先级,用于多个指令同时作用于同一个元素时。比方:

<select>
    <option ng-repeat="i in [1, 2]" ng-bind="i"></option>
</select>

上面的例子中,ng-repeat 指令和 ng-bind 指令同时作用于 option 元素,由于 ng-repeat 的 priority 为1000,ng-bind 的 priority 为0,因而先实行 ng-repeat,然后变量 i 的值才用于 ng-bind 中。

template(String or Function)

HTML模板内容,用于以下状况之一:

  • 替代元素的内容(默许状况)。

  • 替代元素自身(假如 replace 选项为 true)。

  • 将元素的内容包裹起来(假如 transclude 选项为 true,背面会细说)。

值可所以:

  • 一个 HTML 字符串。比方:<div>my name is {{name}}</div>

  • 一个函数,吸收两个参数 tElement(元素自身) 和 tAttrs(元素的属性鸠合),返回 HTML 字符串。

templateUrl(String or Function)

templateUrl 和 template 作用雷同,但模板内容是从 $templateCache 效劳或长途 url 加载。

值可所以:

  • 一个字符串,AngularJS 会先从 $templateCache 中查找是不是缓存了对应值,假如没有则尝试 ajax 加载。比方:在页面中有以下 script:

    <script type="text/ng-template" id="Hello.html">
        <p>Hello</p>
    </script>

    AngularJS 会将 type="text/ng-template"script 标签中的内容以 id 值为 key 缓存到 $templateCache 效劳中,此时能够设置 templateUrl: 'Hello.html'

  • 一个函数,吸收两个参数 tElement(元素自身) 和 tAttrs(元素的属性鸠合),返回 url 地点。

transclude(Boolean)

官方文档的解释为:编译元素的内容,使其在指令内部可用。该选项平常和 ng-transclude 指令一同运用。

假如 transclude 设置为 true,则元素的内容会被放到模板中设置了 ng-transclude 指令的元素中。比方:

app.directive('testTransclude', [
    function () {
        return {
            restrict: 'E',
            transclude: true,
            template:
                '<div>\
                    <p>指令内部段落</p>\
                    <div ng-transclude></div>\
                </div>'
        };
    }
]);
<test-transclude>
    <p>该段落会被放到指令内部</p>
</test-transclude>

上面天生后的 DOM 构造为:

《AngularJS进修笔记(2) --- 指令参数和scope绑定战略》

restrict(String)

指令的运用情势。

值能够为:

  • 'E' – 指令作为元素运用

  • 'A' – 指令作为属性运用

  • 'C' – 指令作为类名运用

  • 'M' – 指令作为解释运用(不经常使用)

可所以以上值的组合,如 restrict: 'EA' 示意指令既能够作为属性运用,也能够作为元素运用。

scope(Boolean or Object)

关于 scope 选项将会在背面的指令 scope 中细说。

controller(Function)

平常状况下不须要运用指令的 controller,只需运用 link 就够了,背面会细说 link 函数。

controller 的场景是该指令(a)会被其他指令(b)require 的时刻,在 b 的指令里能够传入 a 的这个 controller,目标是为了指令间的复用和交换。而 link 只能在指令内部中定义行动,没法做到如许。

controllerAs(String)

为控制器指定别号,如许能够在须要控制器的处所运用该名字举行注入。

require(String or Array)

示意指令依靠于一个或多个指令,并注入所依靠指令的控制器到 link 函数的第四个参数中。假如所依靠的指令不存在,或所依靠指令的控制器不存在则会报错。

依靠称号前缀能够为:

  • (没有前缀) – 在当前元素中查找依靠指令的控制器,假如不存在则报错。

  • ? – 在当前元素中查找依靠指令的控制器,假如不存在传 nulllink 中。

  • ^ – 在当前元素及父元素中查找依靠指令的控制器,假如不存在则报错。

  • ?^ – 在当前元素及父元素中查找依靠指令的控制器,假如不存在传 nulllink 中。

例子:

app.directive('validate', [
    function () {
        return {
            restrict: 'A',
            require: 'ngModel',
            link: function (scope, ele, attrs, ngModelCtrl) {
                // 监听值变化
                ngModelCtrl.$viewChangeListeners.push(function () {
                    scope.validateResult = ngModelCtrl.$viewValue === 'Heron';
                });
            }
        };
    }
]);

app.controller('myCtrl', [
    '$scope',
    '$cookieStore',
    function ($scope, $cookieStore) {
        $scope.name = 'Heron';

        $scope.sayHi = function (name, age) {
            alert('Hello ' + name + ', your age is ' + age);
        }
    }
]);
<div ng-controller="myCtrl">
    <input type="text" ng-model="name" validate>
    <p>
        validate 效果:{{validateResult}}
    </p>
</div>

运转效果如图:

《AngularJS进修笔记(2) --- 指令参数和scope绑定战略》

compile(Function)link(Function)

竖立的竖立历程能够分为编译(compile)阶段和链接(link)阶段,因而二者放一同讲。

二者区分在于:

  • compile 函数的作用是对指令的模板举行转换。

  • link 函数的作用是在视图和模子之间竖立关联,包含注册事宜监听函数和更新 DOM 操纵。

  • scope 在链接阶段才会被绑定到元素上,因而 compile 函数中没有入参 scope

  • 关于同一个指令的多个示例,compile 函数只会实行一次,而 link 函数在每一个实例中都邑实行。

  • 假如自定义了 compile 函数,则自定义的 link 函数 无效,而是运用 compile 函数 返回的 link 函数。

指令 scope

scope 选项有三种值:

  • false – 运用父 scope。转变父 scope 会影响指令 scope,反之亦然。

  • true – 继续父 scope,并竖立本身的 scope。转变父 scope 会影响指令 scope,而转变指令 scope 不会影响父 scope

  • {} – 不继续父 scope,竖立自力的 scope。假如不运用双向绑定战略(背面会讲),转变父 scope 不会影响指令 scope,反之亦然。

例子:

app.controller('myCtrl', [
    '$scope',
    '$cookieStore',
    function ($scope, $cookieStore) {
        $scope.scopeFalse = 'Heron';
        $scope.scopeTrue = 'Heron';
        $scope.scopeObject = 'Heron';
    }
]);
 
app.directive('directiveFalse', [
    function () {
        return {
            restrict: 'EA',
            scope: false,
            template: 
                '<div>\
                    <p>\
                        <span>指令 scope: </span>\
                        <input type="text" ng-model="scopeFalse">\
                    </p>\
                </div>'
        };
    }
]);
app.directive('directiveTrue', [
    function () {
        return {
            restrict: 'EA',
            scope: true,
            template: 
                '<div>\
                    <p>\
                        <span>指令 scope: </span>\
                        <input type="text" ng-model="scopeTrue">\
                    </p>\
                </div>'
        };
    }
]);
app.directive('directiveObject', [
    function () {
        return {
            restrict: 'EA',
            scope: {},
            template: 
                '<div>\
                    <p>\
                        <span>指令 scope: </span>\
                        <input type="text" ng-model="scopeObject">\
                    </p>\
                </div>',
            link: function (scope) {
                // 由于运用自力scope,因而须要本身定义变量
                scope.scopeObject = 'Heron';
            }
        };
    }
]);
<div ng-controller="myCtrl">
    <h3>scope: false</h3>
    <p>
        <span>父 scope: </span>
        <input type="text" ng-model="scopeFalse">
    </p>
    <directive-false></directive-false>
    <h3>scope: true</h3>
    <p>
        <span>父 scope: </span>
        <input type="text" ng-model="scopeTrue">
    </p>
    <directive-true></directive-true>
    <h3>scope: {}</h3>
    <p>
        <span>父 scope: </span>
        <input type="text" ng-model="scopeObject">
    </p>
    <directive-object></directive-object>
</div>

运转效果如图:

《AngularJS进修笔记(2) --- 指令参数和scope绑定战略》

针对自力 scope,能够经由过程在对象中声明怎样从外部传入参数。有以下三种绑定战略:

  • @ – 运用 DOM 属性值单项绑定到指令 scope 中。此时绑定的值老是一个字符串,由于 DOM 的属性值是一个字符串。

    <div my-directive age="26"></div>
    
    scope: {
        age: '@'
    }
  • = – 在父 scope 和指令 scope 之间竖立双向绑定。

    <div my-directive age="age"></div>
    
    scope: {
        age: '='
    }
  • & – 运用父 scope 的高低文实行函数。平经常使用于绑定函数。

    <div my-directive sayHi="sayHi()"></div>
    
    scope: {
        sayHi: '&'
    }

绑定函数时,偶然须要向指令外部通报参数,以下:

app.controller('myCtrl', [
    '$scope',
    '$cookieStore',
    function ($scope, $cookieStore) {
        $scope.name = 'Heron';

        $scope.sayHi = function (name, age) {
            alert('Hello ' + name + ', your age is ' + age);
        };
    }
]);

app.directive('myDirective', [
    function () {
        return {
            restrict: 'E',
            replace: true,
            scope: {
                clickMe: '&'
            },
            template: 
                '<div>\
                    <button class="btn btn-info" ng-click="clickMe({ age: age })">点我</button>\
                </div>',
            link: function (scope) {
                scope.age = 26;
            }
        };
    }
]);
<div ng-controller="myCtrl">
    <my-directive click-me="sayHi(name, age)"></my-directive>
</div>

运转效果如图:

《AngularJS进修笔记(2) --- 指令参数和scope绑定战略》

申明一下:起首声明 clickMe: '&' 运用父 scope 的环境实行 clickMe 函数,然后在通报给指令时声明 click-me="sayHi(name, age)",示意父 scope 的 sayHi 要领须要两个参数,一个是 name,一个是 age,然后再指令中运用对象 {} 的体式格局向外通报参数,如 ng-click="clickMe({ age: age })",示意向指令外通报 age 参数,sayHi 要领从指令拿到 age 参数,再从本身的高低文中拿到 name 参数。

结语

AngularJS 指令的开辟和运用一成不变,也有很多坑,愿望人人注意,也愿望人人能在批评区多多交换心得。

    原文作者:hetianqi
    原文地址: https://segmentfault.com/a/1190000008369347
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞