深入浅析Angular中Directive的用法

本篇文章给大家详细介绍一下angular directive,了解它的用法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。

深入浅析Angular中Directive的用法

Angular Directive 学习

学习目的:为了更好的了解 ng directive 的使用方法。

Directive可能是AngularJS中比较复杂的一个东西了。一般我们将其理解成指令。AngularJS自带了不少预设的指令,比如ng-app,ng-controller这些。可以发现个特点,AngularJS自带的指令都是由ng-打头的。

那么,Directive究竟是个怎么样的一个东西呢?我个人的理解是这样的:将一段html、js封装在一起,形成一个可复用的独立个体,具体特定的功能。下面我们来详细解读一下Directive的一般性用法。

AnguarJS directive的常用定义格式以及参数说明

看下面的代码:

var myDirective = angular.module('directives', []);myDirective.directive('directiveName', function($inject) {    return {        template: '
',        replace: false,        transclude: true,        restrict: 'E',        scope: {},        controller: function($scope, $element) {        },        complie: function(tElement, tAttrs, transclude) {            return {                pre: function preLink(scope, iElement, iAttrs, controller) {                },                post: function postLink(scope, iElement, iAttrs, controller) {                }            };        },        link: function(scope, iElement, iAttrs) {        }    };});

登录后复制这里直接return了一个object,对象中包括比较多的属性,这些属性都是对自定义directive的定义。详细的含义,下面会继续说明。return对象参数说明

return {    name: '',    priority: 0,    terminal: true,    scope: {},    controller: fn,    require: fn,    restrict: '',    template: '',    templateUrl: '',    replace: '',    transclude: true,    compile: fn,    link: fn}

登录后复制

相关教程推荐:《angular教程》

如上所示,return的对象中会有很多的属性,这行属性都是用来定义directive的。

下面我们来一个个的说明他们的作用。

name

表示当前scope的名称,一般声明时使用默认值,不用手动设置此属性。

priority

优先级。当有多个directive定义在同一个DOM元素上时,有时需要明确他们的执行顺序。这个属性用于在directive的compile function调用之前进行排序。如果优先级相同,则执行顺序是不确定的(根据经验,优先级高的先执行,相同优先级时按照先绑定后执行)。

teminal

最后一组。如果设置为true,则表示当前的priority将会成为最后一组执行的directive,即比此directive的priority更低的directive将不会执行。同优先级依然会执行,但是顺序不确定。

scope

true将为这个directive创建一个新的scope。如果在同一个元素中有多个directive需要新的scope的话,它还是只会创建一个scope。新的作用域规则不适用于根模版,因为根模版往往会获得一个新的scope。{}将创建一个新的、独立的scope,此scope与一般的scope的区别在于它不是通过原型继承于父scope的。这对于创建可复用的组件是很有帮助的,可以有效的防止读取或者修改父级scope的数据。这个独立的scope会创建一个拥有一组来源于父scope的本地scope属性hash集合。这些本地scope属性对于模版创建值的别名很有帮助。本地的定义是对其来源的一组本地scope property的hash映射。

controller

controller构造函数。controller会在pre-linking步骤之前进行初始化,并允许其他directive通过指定名称的require进行共享。这将允许directive之间相互沟通,增强相互之间的行为。controller默认注入了以下本地对象:$scope 与当前元素结合的scope$element 当前的元素$attrs 当前元素的属性对象$transclude 一个预先绑定到当前scope的转置linking function

require

请求另外的controller,传入当前directive的linking function中。require需要传入一个directive controller的名称。如果找不到这个名称对应的controller,那么将会抛出一个error。名称可以加入以下前缀:? 不要抛出异常。这将使得这个依赖变为一个可选项^ 允许查找父元素的controller

restrict

EACM的子集的字符串,它限制了directive为指定的声明方式。如果省略的话,directive将仅仅允许通过属性声明E 元素名称:A 属性名:C class名:M 注释:

template

如果replace为true,则将模版内容替换当前的html元素,并将原来元素的属性、class一并转移;如果replace为false,则将模版元素当作当前元素的子元素处理。

templateUrl

与template基本一致,但模版通过指定的url进行加载。因为模版加载是异步的,所有compilation、linking都会暂停,等待加载完毕后再执行。

replace

如果设置为true,那么模版将会替换当前元素,而不是作为子元素添加到当前元素中。(为true时,模版必须有一个根节点)

transclude

编译元素的内容,使它能够被directive使用。需要在模版中配合ngTransclude使用。transclusion的有点是linking function能够得到一个预先与当前scope绑定的transclusion function。一般地,建立一个widget,创建独立scope,transclusion不是子级的,而是独立scope的兄弟级。这将使得widget拥有私有的状态,transclusion会被绑定到父级scope中。(上面那段话没看懂。但实际实验中,如果通过调用myDirective,而transclude设置为true或者字符串且template中包含的时候,将会将的编译结果插入到sometag的内容中。如果any的内容没有被标签包裹,那么结果sometag中将会多了一个span。如果本来有其他东西包裹的话,将维持原状。但如果transclude设置为’element’的话,any的整体内容会出现在sometag中,且被p包裹)true/false 转换这个directive的内容。(这个感觉上,是直接将内容编译后搬入指定地方)‘element’ 转换整个元素,包括其他优先级较低的directive。(像将整体内容编译后,当作一个整体(外面再包裹p),插入到指定地方)

compile

这里是compile function,将在下面实例详细说明

link

这里是link function ,将在下面实例详细讲解。这个属性仅仅是在compile属性没有定义的情况下使用。

关于scope

这里关于directive的scope为一个object时,有更多的内容非常有必要说明一下。看下面的代码:

scope: {    name: '=',    age: '=',    sex: '@',    say: '&'}

登录后复制

这个scope中关于各种属性的配置出现了一些奇怪的前缀符号,有=,@,&,那么这些符号具体的含义是什么呢?再看下面的代码:

html

复制代码

登录后复制javascript

function Controller($scope) {    $scope.name = 'Pajjket';    $scope.age = 99;    $scope.sex = '我是男的';    $scope.say = function() {        alert('Hello,我是弹出消息');    };}

登录后复制

可以看出,几种修饰前缀符的大概含义:

=: 指令中的属性取值为Controller中对应$scope上属性的取值@: 指令中的取值为html中的字面量/直接量&: 指令中的取值为Controller中对应$scope上的属性,但是这个属性必须为一个函数回调下面是更加官方的解释:=或者=expression/attr

在本地scope属性与parent scope属性之间设置双向的绑定。如果没有指定attr名称,那么本地名称将与属性名称一致。

例如:中,widget定义的scope为:{localModel: ‘=myAttr’},那么widget scope property中的localName将会映射父scope的parentModel。如果parentModel发生任何改变,localModel也会发生改变,反之亦然。即双向绑定。

@或者@attr建立一个local scope property到DOM属性的绑定。因为属性值总是String类型,所以这个值总返回一个字符串。如果没有通过@attr指定属性名称,那么本地名称将与DOM属性的名称一致。例如:,widget的scope定义为:{localName: ‘@myAttr’}。那么,widget scope property的localName会映射出”hello “转换后的真实值。当name属性值发生改变后,widget scope的localName属性也会相应的改变(仅仅是单向,与上面的=不同)。那么属性是在父scope读取的(不是从组件的scope读取的)

&或者&attr提供一个在父scope上下文中执行一个表达式的途径。如果没有指定attr的名称,那么local name将与属性名一致。

例如:

,widget的scope定义为:{localFn:’increment()’},那么isolate scope property localFn会指向一个包裹着increment()表达式的function。一般来说,我们希望通过一个表达式,将数据从isolate scope传到parent scope中。这可以通过传送一个本地变量键值的映射到表达式的wrapper函数中来完成。例如,如果表达式是increment(amount),那么我们可以通过localFn({amount:22})的方式调用localFn以指定amount的值。

directive 实例讲解

下面的示例都围绕着上面所作的参数说明而展开的。

directive声明实例

// 自定义directivevar myDirective = angular.modeule('directives', []);myDirective.directive('myTest', function() {    return {        restrict: 'EMAC',        require: '^ngModel',        scope: {            ngModel: '='        },        template: '

Weather for {{ngModel}}

'    };});// 定义controllervar myControllers = angular.module('controllers', []);myControllers.controller('testController', [    '$scope',    function($scope) {        $scope.name = 'this is directive1';    }]);var app = angular.module('testApp', [    'directives',    'controllers']);    
                                    

登录后复制

template与templateUrl的区别和联系

templateUrl其实根template功能是一样的,只不过templateUrl加载一个html文件,上例中,我们也能发现问题,template后面根的是html的标签,如果标签很多呢,那就比较不爽了。可以将上例中的,template改一下。

myDirective.directive('myTest', function() {    return {        restrict: 'EMAC',        require: '^ngModel',        scope: {            ngModel: '='        },        templateUrl:'../partials/tem1.html'   //tem1.html中的内容就是上例中template的内容。    }});

登录后复制

scope重定义

//directives.js中定义myAttrmyDirectives.directive('myAttr', function() {    return {        restrict: 'E',        scope: {            customerInfo: '=info'        },        template: 'Name: {{customerInfo.name}} Address: {{customerInfo.address}}
' +                  'Name: {{vojta.name}} Address: {{vojta.address}}'    };});//controller.js中定义attrtestmyControllers.controller('attrtest',['$scope',    function($scope) {        $scope.naomi = {            name: 'Naomi',            address: '1600 Amphitheatre'        };        $scope.vojta = {            name: 'Vojta',            address: '3456 Somewhere Else'        };    }]);// html中    
            

登录后复制

其运行结果如下:

Name: Naomi Address: 1600 Amphitheatre      //有值,因为customerInfo定义过的Name: Address:                              //没值 ,因为scope重定义后,vojta是没有定义的

登录后复制

我们将上面的directive简单的改一下,

myDirectives.directive('myAttr', function() {    return {        restrict: 'E',        template: 'Name: {{customerInfo.name}} Address: {{customerInfo.address}}
' +                  'Name: {{vojta.name}} Address: {{vojta.address}}'    };});

登录后复制运行结果如下:

Name: Address:Name: Vojta Address: 3456 Somewhere Else

登录后复制

因为此时的directive没有定义独立的scope,customerInfo是undefined,所以结果正好与上面相反。

transclude的使用

transclude的用法,有点像jquery里面的$().html()功能

myDirective.directive('myEvent', function() {    return {        restrict: 'E',        transclude: true,        scope: {            'close': '$onClick'      //根html中的on-click="hideDialog()"有关联关系        },        templateUrl: '../partials/event_part.html'    };});myController.controller('eventTest', [    '$scope',    '$timeout',    function($scope, $timeout) {        $scope.name = 'Tobias';        $scope.hideDialog = function() {            $scope.dialogIsHidden = true;            $timeout(function() {                $scope.dialogIsHidden = false;            }, 2000);        };    }]);

登录后复制

    
                    Check out the contents, {{name}}!            
    ×    

登录后复制说明:这段html最终的结构应该如下所示:

    
        
            Check out the contents, {{name}}!        
    

登录后复制将原来的html元素中的元素Check out the contents, !插入到模版的中,还会另外附加一个标签。controller,link,compile之间的关系

myDirective.directive('exampleDirective', function() {    return {        restrict: 'E',        template: '

Hello {{number}}!

',        controller: function($scope, $element){            $scope.number = $scope.number + "22222 ";        },        link: function(scope, el, attr) {            scope.number = scope.number + "33333 ";        },        compile: function(element, attributes) {            return {                pre: function preLink(scope, element, attributes) {                    scope.number = scope.number + "44444 ";                },                post: function postLink(scope, element, attributes) {                    scope.number = scope.number + "55555 ";                }            };        }    }});//controller.js添加myController.controller('directive2',[    '$scope',    function($scope) {        $scope.number = '1111 ';    }]);//html    
            

登录后复制上面小例子的运行结果如下:

Hello 1111 22222 44444 5555 !

登录后复制

由结果可以看出来,controller先运行,compile后运行,link不运行。我们现在将compile属性注释掉后,得到的运行结果如下:Hello 1111 22222 33333 !

由结果可以看出来,controller先运行,link后运行,link和compile不兼容。一般地,compile比link的优先级要高。

更多编程相关知识,请访问:编程入门!!

以上就是深入浅析Angular中Directive的用法的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2715002.html

(0)
上一篇 2025年3月7日 21:39:45
下一篇 2025年2月26日 18:38:54

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • 20个优秀的Angular开源项目,你了解几个呢?

    本篇文章给大家分享20个你值得了解的angular开源项目。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 相关教程推荐:《angular教程》 1.Angular-CLI – angular工具命令行 Git…

    2025年3月7日 编程技术
    200
  • 详解Angular中的Route路由

    本篇文章带大家一起了解angular中的路由(route)。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 Angular 路由(Route) 我们可以将路由器理解成控制整个应用状态的视图对象, 每个应用都有一个路由器; …

    2025年3月7日
    200
  • 详解Angular中的NgModule(模块)

    本篇文章带大家详细了解一下angular中的ngmodule(模块)。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 Angular 模块(NgModule) Angular 应用是模块化的, 它拥有自己的模块化系统, 称…

    2025年3月7日
    200
  • 深入了解Angular中的Component组件

    本篇文章给大家介绍一下angular中的component组件。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 Angular 组件(Component) 组件(Component) 是构成 Angular 应用的基础和核…

    2025年3月7日
    200
  • Angular开发者必须学习的19件事

    本篇文章给大家介绍一下成为优秀angular开发者所需要学习的19件事。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 一款to-do app基本等同于前端开发的“Hello world”。虽然涵盖了创建应用程序的CRUD…

    2025年3月7日
    200
  • 详解Angular中的依赖注入模式

    本篇文章给大家详细介绍一下angular中的依赖注入模式。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 Angular 依赖注入模式 依赖注入: Dependency Injection 简称 DI 依赖注入模式要解决的…

    2025年3月7日
    200
  • 详解Angular中的模板语法

    本篇文章给大家详细介绍一下angular中的模板语法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 相关教程推荐:《angular教程》 插值表达式 test-interpolation.component.ts @Co…

    2025年3月7日
    200
  • 详解Angular中组件间通讯的几种方法

    本篇文章带大家详细了解一下angular中组件间通讯的几种。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 Angular 组件间的通讯 组件间三种典型关系: 父好组件之间的交互(@Input/@Output/模板变量/@…

    2025年3月7日
    200
  • 深入了解Angular组件中的生命周期钩子

    本篇文章带大家了解一下angular组件生命周期钩子。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 Angular 组件生命周期钩子 其中,红色标记的生命周期钩子只调用一次,绿色部分会被反复调用,执行顺序依次由上而下。 …

    2025年3月7日
    200
  • 深入了解Angular中的表单

    本篇文章给大家详细介绍一下angular中的表单。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 Angular 表单 什么是模板式表单 表单的数据模型是通过组件模板中的相关指令来定义的, 因为使用这种方式定义表单的数据模…

    2025年3月7日
    200

发表回复

登录后才能评论