先來說說自定義指令
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>效果:
點擊這里查看效果。
小結
本篇只是大致了解了自定義指令,下一步,我們還要深入了解自定義指令的相關應用。



