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

你知道用AngularJs怎么定义指令吗?

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

你知道用AngularJs怎么定义指令吗?

前言最近学习了下angularjs指令的相关知识,也参考了前人的一些文章,在此总结下。欢迎批评指出错误的地方。Angularjs指令定义的APIAngularJs的指令定义大致如下
angular.module("app",[]).directive("directiveName",function(){    return{     //通过设置项来定义    };})

其中return返回的对象包含很多参数,下面一一说明

1.restrict

(字符串)可选参数,指明指令在DOM里面以什么形式被声明;

取值有:E(元素),A(属性),C(类),M(注释),其中默认值为A;

E(元素):<directiveName></directiveName>A(属性):<div directiveName='exPRession'></div>C(类): <div class='directiveName'></div>M(注释):<--directive:directiveName expression-->

例如restrict:‘EA’ 则表示指令在DOM里面可用元素形式和属性形式被声明;

一般来说,当你创建一个有自己模板组件的时候,需要使用元素名,如果仅仅是为为已有元素添加功能的话,就使用属性名

注意:如果想支持IE8,则最好使用属性和类形式来定义。另外Angular从1.3.x开始, 已经放弃支持IE8了.2.priority

(数字),可选参数,指明指令的优先级,若在单个DOM上有多个指令,则优先级高的先执行;

设置指令的优先级算是不常用的

比较特殊的的例子是,angularjs内置指令的ng-repeat的优先级为1000,ng-init的优先级为450;

3.terminal

(布尔型),可选参数,可以被设置为true或false,若设置为true,则优先级低于此指令的其他指令则无效,不会被调用(优先级相同的还是会执行)

4.template(字符串或者函数)可选参数,可以是:(1)一段HTML文本
angular.module("app",[]).directive("hello",function(){                return{                 restrict:'EA',                 template:"<div><h3>hello world</h3></div>"                };            })
HTML代码为:<hello></hello>
结果渲染后的HTML为:<hello>   <div><h3>hello world</h3></div></hello>
(2)一个函数,可接受两个参数tElement和tAttrs

其中tElement是指使用此指令的元素,而tAttrs则实例的属性,它是一个由元素上所有的属性组成的集合(对象)形如:

{title:‘aaaa’,name:'leifeng'}

下面让我们看看template是一个函数时候的情况

angular.module("app",[]).directive("directitle",function(){                return{                 restrict:'EAC',                 template: function(tElement,tAttrs){                    var _html = '';                    _html += '<div>'+tAttrs.title+'</div>';                    return _html;                 }                };            })
HTML代码:<directitle title='biaoti'></directitle>
渲染之后的HTML:<div>biaoti</div>

因为一段HTML文本,阅读跟维护起来都是很麻烦的,所用通常会使用templateUrl这个。

5.templateUrl(字符串或者函数),可选参数,可以是

(1)一个代表HTML文件路径的字符串

(2)一个函数,可接受两个参数tElement和tAttrs(大致同上)

注意:在本地开发时候,需要运行一个服务器,不然使用templateUrl会报错Cross Origin Request Script(CORS)错误

由于加载html模板是通过异步加载的,若加载大量的模板会拖慢网站的速度,这里有个技巧,就是先缓存模板

你可以再你的index页面加载好的,将下列代码作为你页面的一部分包含在里面。

<script type='text/ng-template' id='woshimuban.html'>           <div>我是模板内容</div></script>

这里的id属性就是被设置在templateUrl上用的。

另一种办法缓存是:

angular.module("template.html", []).run(["$templateCache", function($templateCache) {  $templateCache.put("template.html",    "<div>wo shi mu ban</div>");}]);

6.replace

(布尔值),默认值为false,设置为true时候,我们再来看看下面的例子(对比下在template时候举的例子)

angular.module("app",[]).directive("hello",function(){                return{                 restrict:'EA',                 replace:true,                 template:"<div><h3>hello world</h3></div>"                };            })
HTML代码为:<hello></hello>
渲染之后的代码:<div><h3>hello world</h3></div>

对比下没有开启replace时候的渲染出来的HTML。发现<hello></hello>不见了。

另外当模板为纯文本(即template:"wo shi wen ben")的时候,渲染之后的html代码默认的为文本用span包含。

7.scope

可选参数,(布尔值或者对象)默认值为false,可能取值:

(1)默认值false。

表示继承父作用域;

(2)true

表示继承父作用域,并创建自己的作用域(子作用域);

(3){}

表示创建一个全新的隔离作用域;

7.1首先我们先来了解下scope的继承机制。我们用ng-controller这个指令举例,

我们都知道ng-controller(内置指令)可以从父作用域中继承并且创建一个新的子作用域。如下:

<!doctype html><html ng-app="myApp"><head>  <script src="http://cdn.staticfile.org/angular.js/1.2.10/angular.min.js"></script></head><body>  <div ng-init="aaa='父亲'">    parentNode:{{aaa}}    <div ng-controller="myController">        chrildNode: {{aaa}}    </div>  </div>  <script>    angular.module('myApp', [])    .controller('myController',function($scope){       $scope.aaa = '儿子'    })  </script></body></html>
View Code

这时页面显示是

parentNode:父亲

chrildNode: 儿子

若去掉

 $scope.aaa = '儿子'

则显示

parentNode:父亲

chrildNode: 父亲注意:

1)若一个元素上有多个指令,使用了隔离作用域,则只有其中一个可以生效;

2)只有指令模板中的根元素才能获得一个新的作用域,这时候,scope就被设置为true了;

<!doctype html><html ng-app="myApp"><head>  <script src="http://cdn.staticfile.org/angular.js/1.2.10/angular.min.js"></script></head><body>  <div ng-init="aaa='父亲'">    parentNode:{{aaa}}    <div class='one' ng-controller="myController">        chrildNode: {{aaa}}        <div class='two' ng-controller='myController2'>          {{aaa}}        </div>    </div>  </div>  <script>    angular.module('myApp', [])    .controller('myController',function($scope){      $scope.aaa = '儿子';    })    .controller('myController2',function($scope){      $scope.aaa = '孙女';    })  </script></body></html>
View Code

页面显示为:

parentNode:父亲

chrildNode: cunjieliu孙女

上面中class为one那个div获得了指令ng-controller=’myController‘所创建的新的作用域;

而class为two那个div获得了指令ng-controller=’myController2‘所创建的新的作用域;

这就是“只有指令模板中的根元素才能获得一个新的作用域”;

接下来我们通过一个简单明了的例子来说明scope取值不同的差别

<!doctype html><html ng-app="myApp"><head>  <script src="http://cdn.staticfile.org/angular.js/1.2.10/angular.min.js"></script></head><body>  <div ng-controller='MainController'>        父亲: {{name}}        <input ng-model="name" />        <div my-directive></div>  </div>  <script>    angular.module('myApp', [])        .controller('MainController', function ($scope) {           $scope.name = 'leifeng';        })        .directive('myDirective', function () {            return {                restrict: 'EA',                scope:false,//改变此处的取值,看看有什么不同                template: '<div>儿子:{{ name }}<input ng-model="name"/></div>'            };        });  </script></body></html>
View Code

依次设置scope的值false,true,{},结果发现(大家别偷懒,动手试试哈)

当为false时候,儿子继承父亲的值,改变父亲的值,儿子的值也随之变化,反之亦如此。(继承不隔离)

当为true时候,儿子继承父亲的值,改变父亲的值,儿子的值随之变化,但是改变儿子的值,父亲的值不变。(继承隔离)

当为{}时候,没有继承父亲的值,所以儿子的值为空,改变任何一方的值均不能影响另一方的值。(不继承隔离)

tip:当你想要创建一个可重用的组件时隔离作用域是一个很好的选择,通过隔离作用域我们确保指令是‘独立’的,并可以轻松地插入到任何HTML app中,并且这种做法防止了父作用域被污染;7.2隔离作用域可以通过绑定策略来访问父作用域的属性。

下面看一个例子

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表