AngularJS学习笔记(五)自定义指令(1)
先来说说自定义指令
ng通过内置指令的方式实现了对html的增强,同时也赋予了我们自定义指令的功能,让我们根据实际需求进行指令的定制。自定义指令涉及到模板(template)、作用域(scope)、数据绑定和Dom操作等内容,我也是正在学习中,写的比较肤浅。
如何自定义指令
从简单的写起,我们先来认识几个常用的配置吧,深入点的我也不会哈。。。
App.directive("directiveName",function(){ return { //指令可用在何处,一般有E(Elemenmt)、A(Attribute)、C(Class),还有一个注释,这个就算了吧。默认为A,也就是作为属性用。 restrict: 'E', //是否替换指令元素。一般这样调用元素<dialog></dialog>,当为true的时候,页面就不会出现dialog元素。 replace: true, //指令模板,一般模板复杂的话,可以单独放置一个文件,然后使用templateUrl进行引用。 template: '<div>。。。</div>', //这儿是作用域,如果没有这个配置,则公用所在controller的域;如果有scope,则起到了隔离作用,这儿的key是template的表达式,value指的是元素的属性key。 scope: { key:value } }; });只要这么个定义了,页面上就可以高兴的使用啦。下面来看几个例子吧,实践出真知啊。
例子1.简单的对话框,这个例子有点挫
<!DOCTYPE html> <html ng-app="App"> <head> <link rel="stylesheet" type="text/css" href="http://sandbox.runjs.cn/uploads/rs/394/xjz9g1bv/bootstrap.css"> <script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/394/xjz9g1bv/angular.js"></script> <script type="text/javascript"> var App = angular.module("App", []); App.controller("ctrl", function ($scope) { }); App.directive("dialog",function(){ return { //限制,也就是这个指令可用在何处,一般有E(Elemenmt)、A(Attribute)、C(Class),还有一个注释,这个就算了吧。默认为A,也就是作为属性用。 restrict: 'E', //是否替换指令元素。一般这样调用元素<dialog></dialog>,当为true的时候,页面就不会出现dialog元素。 replace: true, //指令模板,一般模板复杂的话,可以单独放置一个文件,然后使用templateUrl进行引用。 template: '<div><div>{{dialogTitle}}</div><div>{{dialogContent}}</div></div>', //这儿是作用域,如果没有这个配置,则公用所在controller的域;如果有scope,则起到了隔离作用,这儿的key是template的表达式,value指的是元素的属性key。 scope: { //dialogTitle指的是template的{{dialogTitle}} //title是<dialog title='标题'></dialog>中的title;如果元素是这样的:<dialog dialogTitle='标题'></dialog>,则下面的配置可以简写成:dialogTitle:'@' dialogTitle: '@title', dialogContent:'@content' } }; }); </script> </head> <body style='padding-top:10px;'> <div class='container' ng-controller="ctrl"> <dialog title='我是标题' content='这个例子有点挫。。。'></dialog> </div> </body> </html>查看效果:
点击这里查看效果。
这个例子真的好搓啊,内容还有点,样式真是挫,人真的是很感性的啊。估计这个例子大家看不下去了,我来找找Bootstrap的dialog样式吧,看看下个例子吧。
例子2.有模有样的对话框
在这个例子里,我们要使用Bootstrap的模态框相关的样式。额,我们先来看下Bootstrap对模态框的定义:
<div class="modal fade"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button> <h4 class="modal-title">Modal title</h4> </div> <div class="modal-body"> <p>One fine body…</p> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> <button type="button" class="btn btn-primary">Save changes</button> </div> </div><!-- /.modal-content --> </div><!-- /.modal-dialog --> </div><!-- /.modal -->纳尼,这么复杂,这要让我写到template模板里,估计是要写疯了。上面介绍了,template还有个兄弟,叫templateUrl,这个似乎是个地址,可以将复杂的模板内容写到其中,然后链接一下,人生似乎好起来了。
这儿再来点变动,就是:dialog的内容,我想写成这样<dialog>我是内容啊,内容。。。</dialog>,这儿就会用到transclude属性了,当transclude为true的时候,template中应至少有一个根元素,而且内部要有元素有ng-transclude属性,这样才能起来替换作用。
好吧,扯了这么多,估计也没看到,还是来看看代码吧。
<!DOCTYPE html> <html ng-app="App"> <head> <link rel="stylesheet" type="text/css" href="http://sandbox.runjs.cn/uploads/rs/394/xjz9g1bv/bootstrap.css"> <script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/394/xjz9g1bv/angular.js"></script> <script type="text/ng-template" id="dialogDirective"> <div class="modal show"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> <h4 class="modal-title">{{title}}</h4> </div> <div class="modal-body" ng-transclude> </div> <div class="modal-footer"> <button type="button" class="btn btn-primary" >关闭</button> </div> </div><!-- /.modal-content --> </div><!-- /.modal-dialog --> </div><!-- /.modal --> </script> <script type="text/javascript"> var App = angular.module("App", []); App.controller("ctrl", function ($scope) { }); App.directive("dialog",function(){ return { restrict: 'E', replace: true, templateUrl: 'dialogDirective', //transclude是必须的。 transclude:true, scope: { title: '@', } }; }); </script> </head> <body style='padding-top:10px;'> <div class='container' ng-controller="ctrl"> <dialog title='我是标题'> 我是内容啊,我是内容,请回答。。。 </dialog> </div> </body> </html>效果:
点击这里查看效果。
额,效果比上一个似乎好多了呀,但是“关闭”按钮为什么不能用呢???
本来这篇想这么结束的,既然你问到了,那就只好再来一段了,且看下个例子
例子3.带关闭功能的对话框呀
我们上面的例子里对话框倒是美美的,但是关闭呢,为啥关闭不了,这儿又要用到一个新的属性了,link。例子里会充分体现link的用处:
<!DOCTYPE html> <html ng-app="App"> <head> <link rel="stylesheet" type="text/css" href="http://sandbox.runjs.cn/uploads/rs/394/xjz9g1bv/bootstrap.css"> <script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/394/xjz9g1bv/angular.js"></script> <script type="text/ng-template" id="dialogDirective"> <div class='modal show'> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" ng-click="close();"><span aria-hidden="true">×</span></button> <h4 class="modal-title">{{title}}</h4> </div> <div class="modal-body" ng-transclude> </div> <div class="modal-footer"> <!--注意:此处调用的是link方法中scope定义的close方法--> <button type="button" class="btn btn-primary" ng-click="close();" >关闭</button> </div> </div><!-- /.modal-content --> </div><!-- /.modal-dialog --> </div><!-- /.modal --> </script> <script type="text/javascript"> var App = angular.module("App", []); App.controller("ctrl", function ($scope) { }); App.directive("dialog",function(){ return { restrict: 'E', replace: true, templateUrl: 'dialogDirective', //transclude是必须的。 transclude:true, //指令中定义了scope,起到了隔离作用,和ctrl中的scope已经不相关了。 scope: { title: '@', }, link:function(scope,elements,attributes){ //注意:因为指令里定义了scope,所以link函数中的scope只包含指令中title,对于dom的行为,应在link函数中定义。 scope.close=function(){ elements.removeClass('show'); } } }; }); </script> </head> <body style='padding-top:10px;'> <div class='container' ng-controller="ctrl"> <dialog title='我是标题'> 我是内容啊,我是内容,请回答。。。 </dialog> </div> </body> </html>效果:
点击这里查看效果。
小结
本篇只是大致了解了自定义指令,下一步,我们还要深入了解自定义指令的相关应用。