首页 > 网站 > WEB开发 > 正文

指令<AngularJs>

2024-04-27 14:17:33
字体:
来源:转载
供稿:网友

指令<AngularJs>

对于指令,可以把它简单的理解成在特定DOM元素上运行的函数,指令可以扩展这个元素的功能。

首先来看个完整的参数示例再来详细的介绍各个参数的作用及用法:

angular.module('myApp', []) .directive('myDirective', function() {     return {         restrict: String,         PRiority: Number,         terminal: Boolean,         template: String or Template Function:     function(tElement, tAttrs) {...},     templateUrl: String,     replace: Boolean or String,     scope: Boolean or Object,     transclude: Boolean,     controller: String or     function(scope, element, attrs, transclude, otherInjectables) { ... },     controllerAs: String,     require: String,     link: function(scope, iElement, iAttrs) { ... },     compile: // 返回一个对象或连接函数,如下所示:    function(tElement, tAttrs, transclude) {         return {             pre: function(scope, iElement, iAttrs, controller) { ... },             post: function(scope, iElement, iAttrs, controller) { ... }            }         return function postLink(...) { ... }         }     };  });

restrict[string]

restrict是一个可选的参数。用于指定该指令在DOM中以何种形式被声明。默认值是A,即以属性的形式来进行声明。可选值如下:E(元素)

<my-directive></my-directive> 

A(属性,默认值)

<div my-directive="expression"></div> 

C(类名)

<div class="my-directive:expression;"></div> 

M(注释)

<--directive:my-directive expression-->

一般考虑到浏览器的兼容性,强烈建议使用默认的属性就可以即即以属性的形式来进行声明。最后一种方式建议再不要求逼格指数的时候千万不要用。

Code:

 angular.module('app',[])    .directive('myDirective', function () {            return {                 restrict: 'E',                 template: '<a href="http://www.baidu.com">百度</a>'             };        })HtmlCode:<my-directive></my-directive>

效果:

priority[int]

大多数指令会忽略这个参数,使用默认值0,但也有些场景设置高优先级是非常重要甚至是必须的。例如,ngRepeat将这个参数设置为1000,这样就可以保证在同一元素上,它总是在其他指令之前被调用。

terminal[bool]

这个参数用来停止运行当前元素上比本指令优先级低的指令。但同当前指令优先级相同的指令还是会被执行。例如:ngIf的优先级略高于ngView(它们操控的实际就是terminal参数),如果ngIf的表达式值为true,ngView就可以被正常执行,但如果ngIf表达式的值为false,由于ngView的优先级较低就不会被执行。

template[string or function]

template参数是可选的,必须被设置为以下两种形式之一:

  • 一段HTML文本;
  • 一个可以接受两个参数的函数,参数为tElement和tAttrs,并返回一个代表模板的字符串。tElement和tAttrs中的t代表template,是相对于instance的。

首先演示下第二种用法:

angular.module('app',[])    .directive('myDirective', function () {            return {                 restrict: 'EAC',                 template: function (elem, attr) {                    return "<a href='" + attr.value + "'>" + attr.text + "</a>";                }        };    })

HtmlCode:(效果同上,不做演示了)

<my-directive value="http://www.baidu.com" text="百度"></my-directive>        <div my-directive             value="http://www.baidu.com"              text="百度"></div>

templateUrl[string or function]

templateUrl是可选的参数,可以是以下类型:

  • 一个代表外部HTML文件路径的字符串;
  • 一个可以接受两个参数的函数,参数为tElement和tAttrs,并返回一个外部HTML文件路径的字符串。

无论哪种方式,模板的URL都将通过ng内置的安全层,特别是$getTrustedResourceUrl,这样可以保护模板不会被不信任的源加载。 默认情况下,调用指令时会在后台通过Ajax来请求HTML模板文件。加载大量的模板将严重拖慢一个客户端应用的速度。为了避免延迟,可以在部署应用之前对HTML模板进行缓存。

Code:

    angular.module('app',[])    .directive('myDirective', function () {            return {                 restrict: 'AEC',                 templateUrl: function (elem, attr) {                    return attr.value + ".html";  //当然这里我们可以直接指定路径,同时在模板中可以包含表达式                }        };    })

replace[bool]

replace是一个可选参数,如果设置了这个参数,值必须为true,因为默认值为false。默认值意味着模板会被当作子元素插入到调用此指令的元素内部,例如上面的示例默认值情况下,生成的html代码如下:

<my-directive value="http://www.baidu.com" text="百度"><a href="http://www.baidu.com">百度</a></my-directive>

如果设置replace=true

<a href="http://www.baidu.com" value="http://www.baidu.com" text="百度">百度</a>

据我观察,这种效果只有设置restrict="E"的情况下,才会表现出实际效果。

介绍完基本的指令参数后,就要涉及到更重要的作用域参数了...

scope参数[bool or object]

scope参数是可选的,可以被设置为true或一个对象。默认值是false。

如果一个元素上有多个指令使用了隔离作用域,其中只有一个可以生效。只有指令模板中的根元素可以获得一个新的作用域。因此,对于这些对象来说scope默认被设置为true。内置指令ng-controller的作用,就是从父级作用域继承并创建一个新的子作用域。它会创建一个新的从父作用域继承而来的子作用域。这里的继承就不在赘述,和面向对象中的继承基本是一直的。

首先我们来分析一段代码:

       <div ng-app="app" ng-init="name= '祖父'">            <div ng-init="name='父亲'">                第一代:{{ name }}                <div ng-init="name= '儿子'" ng-controller="SomeController">                    第二代: {{ name }}                    <div ng-init="name='孙子'">                        第三代: {{ name }}                    </div>                </div>            </div>        </div> 

我们发现第一代,我们初始化name为父亲,但是第二代和第三代其实是一个作用域,那么他们的name其实是一个对象,因此出现的效果如下:

第一代:父亲第二代: 孙子第三代: 孙子

我们在修改一下代码,把第三代隔离开来再看看效果:

 <div ng-app="app"ng-init="name= '祖父'">            <div ng-init="name='父亲'">                第一代:{{ name }}                <div ng-init="name= '儿子'" ng-controller="SomeController">                    第二代: {{ name }}                    <div ng-init="name='孙子'" ng-controller="SecondController">                        第三代: {{ name }}                    </div>                </div>            </div>        </div>

JsCode:

 angular.module('app', [])        .controller('SomeController',function($scope) {                    })       .controller('SecondController', function ($scope) {            }) 

效果如下:

第一代:父亲第二代: 儿子第三代: 孙子

在修改下代码来看看继承:

       <div ng-app="app"ng-init="name= '祖父的吻'">            <div>                第一代:{{ name }}                <div ng-controller="SomeController">                    第二代: {{ name }}                    <div  ng-controller="SecondController">                        第三代: {{ name }}                    </div>                </div>            </div>        </div> 

效果如下:

第一代:祖父的吻第二代: 祖父的吻第三代: 祖父的吻

如果要创建一个能够从外部原型继承作用域的指令,将scope属性设置为true,简单来说就是可继承的隔离,即不能反向影响父作用域。

再来看个例子:

    angular.module('myApp', [])        .controller('MainController', function ($scope) {        })        .directive('myDirective', function () {            return {                restrict: 'A',                scope:false,//切换为{},true测试                priority: 100,                template: '<div>内部:{{ myProperty }}<input ng-model="myProperty"/></div>'            };        });

Html代码:

 <div ng-controller='MainController' ng-init="myProperty='Hello World!'">        外部: {{ myProperty}}        <input ng-model="myProperty" />        <div my-directive></div>    </div>

当我们改变scope的值我们会发现

false:继承但不隔离

true:继承并隔离

{}:隔离且不继承

transclude

transclude是一个可选的参数。默认值是false。嵌入通常用来创建可复用的组件,典型的例子是模态对话框或导航栏。我们可以将整个模板,包括其中的指令通过嵌入全部传入一个指令中。指令的内部可以访问外部指令的作用域,并且模板也可以访问外部的作用域对象。为了将作用域传递进去,scope参数的值必须通过{}或true设置成隔离作用域。如果没有设置scope参数,那么指令内部的作用域将被设置为传入模板的作用域。

只有当你希望创建一个可以包含任意内容的指令时,才使用transclude: true。

我们来看两个例子-导航栏:

    <div side-box title="TagCloud">        <div class="tagcloud">            <a href="">Graphics</a>            <a href="">ng</a>            <a href="">D3</a>            <a href="">Front-end</a>            <a href="">Startup</a>        </div&g
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表