资讯专栏INFORMATION COLUMN

AngularJS学习笔记(2) --- 指令参数和scope绑定策略

AndroidTraveler / 2719人阅读

摘要:引言指令可以说是的核心,而其开发也是比较困难的,本文主要介绍指令的一些参数和的绑定策略。指令执行的优先级,用于多个指令同时作用于同一个元素时。改变父会影响指令,而改变指令不会影响父。在父和指令之间建立双向绑定。

引言

指令(Directive)可以说是 AngularJS 的核心,而其开发也是比较困难的,本文主要介绍指令的一些参数和scope的绑定策略。

参数

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

{
    priority: 0,
    template: "
", // 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)

指令执行的优先级,用于多个指令同时作用于同一个元素时。例如:

上面的例子中,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 字符串。例如:

my name is {{name}}

一个函数,接收两个参数 tElement(元素本身) 和 tAttrs(元素的属性集合),返回 HTML 字符串。

templateUrl(String or Function)

templateUrl 和 template 作用相同,但模板内容是从 $templateCache 服务或远程 url 加载。

值可以是:

一个字符串,AngularJS 会先从 $templateCache 中查找是否缓存了对应值,如果没有则尝试 ajax 加载。例如:在页面中有如下 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:
                "

指令内部段落

" }; } ]);

    

该段落会被放到指令内部

上面生成后的 DOM 结构为:

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);
        }
    }
]);

validate 结果:{{validateResult}}

运行结果如图:

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: 
                "

指令 scope:

" }; } ]); app.directive("directiveTrue", [ function () { return { restrict: "EA", scope: true, template: "

指令 scope:

" }; } ]); app.directive("directiveObject", [ function () { return { restrict: "EA", scope: {}, template: "

指令 scope:

", link: function (scope) { // 由于使用独立scope,因此需要自己定义变量 scope.scopeObject = "Heron"; } }; } ]);

scope: false

父 scope:

scope: true

父 scope:

scope: {}

父 scope:

运行结果如图:

针对独立 scope,可以通过在对象中声明如何从外部传入参数。有以下三种绑定策略:

@ - 使用 DOM 属性值单项绑定到指令 scope 中。此时绑定的值总是一个字符串,因为 DOM 的属性值是一个字符串。

scope: { age: "@" }

= - 在父 scope 和指令 scope 之间建立双向绑定。

scope: { age: "=" }

& - 使用父 scope 的上下文执行函数。一般用于绑定函数。

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: 
                "
", link: function (scope) { scope.age = 26; } }; } ]);

运行结果如图:

说明一下:首先声明 clickMe: "&" 使用父 scope 的环境执行 clickMe 函数,然后在传递给指令时声明 click-me="sayHi(name, age)",表示父 scope 的 sayHi 方法需要两个参数,一个是 name,一个是 age,然后再指令中使用对象 {} 的方式向外传递参数,如 ng-click="clickMe({ age: age })",表示向指令外传递 age 参数,sayHi 方法从指令拿到 age 参数,再从自己的上下文中拿到 name 参数。

结语

AngularJS 指令的开发和使用千变万化,也有许多坑,希望大家留意,也希望大家能在评论区多多交流心得。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/88126.html

相关文章

  • Angularjs学习笔记指令

    摘要:自定义指令中有很多内置指令,一般都是以开头的比如等等。本文介绍的自定义指令的用法。该参数的意思是替换指令的内容,更改上面的例子。将属性绑定到父控制器的域中学习概念多指令中的参数中增加了的值和的点击函数。 自定义指令 angularjs中有很多内置指令,一般都是以ng开头的;比如:ng-app,ng-click,ng-repeat等等。本文介绍angularjs的自定义指令的用法。 指令...

    LeexMuller 评论0 收藏0
  • Angularjs学习笔记指令

    摘要:自定义指令中有很多内置指令,一般都是以开头的比如等等。本文介绍的自定义指令的用法。该参数的意思是替换指令的内容,更改上面的例子。将属性绑定到父控制器的域中学习概念多指令中的参数中增加了的值和的点击函数。 自定义指令 angularjs中有很多内置指令,一般都是以ng开头的;比如:ng-app,ng-click,ng-repeat等等。本文介绍angularjs的自定义指令的用法。 指令...

    Cristic 评论0 收藏0
  • angularJS directive用法详解

    摘要:可选参数,布尔值或者对象默认值为,可能取值默认值。布尔值或者字符,默认值为这个配置选项可以让我们提取包含在指令那个元素里面的内容,再将它放置在指令模板的特定位置。 前言 最近学习了下angularjs指令的相关知识,也参考了前人的一些文章,在此总结下。 欢迎批评指出错误的地方。 Angularjs指令定义的API showImg(https://segmentfault.com/img...

    hlcc 评论0 收藏0
  • angularjs学习笔记指令input

    摘要:新增的日期选择器。类型必填必填最小长度最大长度正则匹配正则匹配更新触发即使没有使用校验属性,只要数据不符合格式,就会被更新成。 input[text] input一般和ngModel结合使用来实现双向绑定,同时angular提供了很多表单校验的指令 required 必填 ngRequired 必填(ngRequired可以控制是否是必填校验) ngMinlength 最小长度...

    princekin 评论0 收藏0
  • 理解学习AngularJS(一)

    摘要:为指令赋值函数名,即可运行。它也是一个对象,指向应用程序作用域内的所有元素和执行上下文。简而言之,是与指令元素相关联的当前作用域,可以理解为视图和控制器间的一个通道。它们被组织为模块形式,之后可以被另一个引用。 Angularjs Angular是一款主旋律的MVVM框架,框架和传统的库不同: 类库是一些函数的集合,它能帮助你写WEB应用。起主导作用的是你的代码,由你来决定何时使用类...

    EastWoodYang 评论0 收藏0

发表评论

0条评论

AndroidTraveler

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<