angular自定義指令中的transclusion以及自定義指令的嵌套

初衷

寫這篇文章的初衷有如下幾點:html

1.最近項目中須要用到ng的自定義指令,而且還涉及到自定義指令的嵌套。
2.百度和谷歌找到的答案都不盡人意。前端

因此想着本身寫一篇得了。web

事先聲明

事先說明,鄙人剛入前端4月有餘,屬於新蛋一枚,也是初次寫博客(第一次就這麼獻給sf了。),我盡本身最大的努力把我想表達的意思表達出來。好了,廢話很少說,直接奔入主體。chrome

前提

首先,還不知道ng自定義指令的童鞋請戳這篇文章。
http://www.cnblogs.com/lvdaba...
這篇文章分了上中下,三篇,講ng自定義指令已經很詳細了。app

其次,還不知道ng自定義指令中的transclusion是啥玩意童鞋請戳這篇文章。
http://www.html-js.com/articl...
這篇文章採用口語化的表達方式詼諧的講述了何爲transclusion。ui

好了,到這裏,咱們正式再次進入主題。spa

transclusion的值

咱們先建立一個app,代碼以下rest

var app=angular.module('myApp', []);
app.controller("testController",function($scope){
    
});

咱們都知道transclusion是自定義指令的的配置項,它的值有如下幾種狀況:code

1.boolean類型,也就是爲true,或者false,固然,默認爲false。
2.Object類型,能夠是一個對象。
3.element類型,還能夠是一個元素。(表示:我目前尚未玩過element。)htm

transclusion爲boolean時

好了,先來講說其值爲boolean類型的時候吧。
建立一個自定義指令,設置其transclusion爲true。代碼以下:

app.directive('popSelect',[function(){
  return {
    restrict: 'AE',
    scope:{
            
    },
    transclude:true,
    replace:true,
    template:
       '<div>'+
          '<div>'+
              '<input type="text" ng-model="input" ng-focus="hasDate=true"/>'+
           '</div>'+
           '<div ng-transclude></div>'+
           '<div>這是popselect指令的內容</div>'+
        '</div>',   
        link:function(scope, elem, attrs){
          
        }  
    }
}]);

你們應該有看到在template裏面多了一個東西是'<div ng-transclude></div>',看到就能夠了,在這裏留個懸念。

既然是自定義指令的嵌套,那好歹也要有兩個指令吧,廢話很少說,再建立一個指令,此指令做爲兒子被別人嵌套,而上面那個嵌套別人的指令咱們叫作父親。代碼以下:

app.directive('childElem',[function(){
    return {
        restrict: 'AE',
        replace:true,
        template:'<div>'+
                    '<div>這是child指令的內容</div>'+
                 '</div>',   
        link:function(scope, elem, attrs){
          
        }  
    }
}])

父親和兒子都建立完成了,那咱們來看看html裏面是怎麼嵌套了。直接上代碼:

<pop-select>
    <child-elem></child-elem>
</pop-select>

沒錯,html就是這麼簡單就能夠了,看看頁面是啥效果:

圖片描述

看到沒,兒子的template內容被嵌入進父親的template(姑且認爲是template吧),那麼它被嵌入到父親的template的哪裏了呢,咱們看看控制檯。

圖片描述

你們有沒有發現什麼,上圖紅框中的位置是否是剛好就是父親的template的'<div ng-transclude></div>'這句話所在位置呀。

沒錯,只要你的指令中嵌套其餘的指令,那麼你在父親的配置項中設置transclude:true,而且在template中你須要的地方加上'<div ng-transclude></div>'這句嵌套話,那麼ng將自動把兒子的內容加入到'<div ng-transclude></div>'這個標籤中來,請仔細看控制檯紅框的圖片。

如今你們自動transclude:true怎麼用了吧。

transclusion爲object時

這裏有人就要問了:你這是嵌套一個兒子啊,若是我家錢多,我土豪,我要生不少個兒子那怎麼辦?

那此時就要使用transclude的值爲object了。廢話很少說再次上代碼。

app.directive('parentDirective',[function(){
  return {
     restrict: 'AE',
     transclude:{
         'child1':"childElem",
          'child2':"childElem2",
           'child3':"childElem3"
     },
     replace:true,
     template:
       '<div>'+
          '<div>'+
             '<input type="text" ng-model="input" value="這是parant指令"/>'+
          '</div>'+   
          '<div ng-transclude="child2"></div>'+
          '<div ng-transclude="child3"></div>'+
          '<div ng-transclude="child1"></div>'+
       '</div>',   
        link:function(scope, elem, attrs){
          
        }  
    }
}]);

你們注意到這一次父親的transclude是一個對象

{
            'child1':"childElem",
            'child2':"childElem2",
            'child3':"childElem3"
         }

在父親的template中還有這樣三句話:

'<div ng-transclude="child2"></div>'+
      '<div ng-transclude="child3"></div>'+
      '<div ng-transclude="child1"></div>'+

你們可能注意到這三句話中的child1,child2,child3怎麼和父親的transclude值中的三個屬性child1,child2,child3一毛同樣啊。猜猜唄,我想有人應該知道是怎麼玩了。

那父親的transclude值中的childElem,childElem2,childElem3這三個是啥玩意?別急嘛。這不,父親尚未兒子嗎?來,給他三個兒子。

首先是大兒子:

app.directive('childElem',[function(){
    return {
        restrict: 'AE',
        replace:true,
        template:'<div>'+
                    '<div>這是child指令的內容</div>'+
                 '</div>',   
        link:function(scope, elem, attrs){
          
        }  
    }
}])

而後是二兒子:

app.directive('childElem2',[function(){
    return {
        restrict: 'AE',
        replace:true,
        template:'<div>'+
                    '<div>這是childElem2指令的內容</div>'+
                 '</div>',   
        link:function(scope, elem, attrs){
          
        }  
    }
}])

最後是三兒子:

app.directive('childElem3',[function(){
    return {
        restrict: 'AE',
        replace:true,
        template:'<div>'+
                    '<div>這是childElem3指令的內容</div>'+
                 '</div>',   
        link:function(scope, elem, attrs){
          
        }  
    }
}])

兒子們到齊了,接下來就該html了。繼續上代碼:

<parent-directive>
    <child-elem></child-elem>
    <child-elem2></child-elem2>
    <child-elem3></child-elem3>
</parent-directive>

那麼頁面效果是啥樣子呢?看下圖:

圖片描述

看,三個的兒子的內容和父親的內容都顯示出來了。

讓咱們再看看控制檯:

圖片描述

三個紅框中的內容就是三個兒子的template了。

你們如今應該明白了吧,沒錯。當父親的transclude是一個對象時,那麼屬性名就是你本身起的名字, 值就是你須要嵌入的兒子的名字。而後你再在父親的template裏面寫上'<div ng-transclude="你起好的屬性名字"></div>',這樣ng就能知道你是想把兒子嵌入到父親的哪裏了。

好了,尚未不明白的麼。若是不明白請看第二遍。哈哈、

所有示例代碼

最後,附上本例中的所有代碼。

<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
</head>
<body ng-controller="testController">
    <h1>嵌套一個指令</h1>
       <pop-select>
          <child-elem></child-elem>
       </pop-select>

    <h1>&nbsp;</h1>

    <h1>嵌套多個指令</h1>
       <parent-directive>
           <child-elem></child-elem>
           <child-elem2></child-elem2>
           <child-elem3></child-elem3>
       </parent-directive>
</body>
<script src="https://staticfile.qnssl.com/angular.js/1.5.0-rc.0/angular.min.js"></script>
<script>
   var app=angular.module('myApp', []);
   app.controller("testController",function($scope){
    
   });
   app.directive('popSelect',[function(){
      return {
        restrict: 'AE',
        scope:{
            
        },
        transclude:true,
        replace:true,
        template:'<div>'+
                    '<div><input type="text" ng-model="input" ng-focus="hasDate=true"/></div>'+
                    '<div ng-transclude></div>'+
                    '<div>這是popselect指令的內容</div>'+
                 '</div>',   
        link:function(scope, elem, attrs){
          
        }  
    }
}]);

app.directive('childElem',[function(){
    return {
        restrict: 'AE',
        replace:true,
        template:'<div>'+
                    '<div>這是child指令的內容</div>'+
                 '</div>',   
        link:function(scope, elem, attrs){
          
        }  
    }
}])

app.directive('parentDirective',[function(){
  return {
     restrict: 'AE',
     transclude:{
         'child1':"childElem",
          'child2':"childElem2",
           'child3':"childElem3"
     },
     replace:true,
     template:
       '<div>'+
          '<div>'+
             '<input type="text" ng-model="input" value="這是parant指令"/>'+
          '</div>'+   
          '<div ng-transclude="child2"></div>'+
          '<div ng-transclude="child3"></div>'+
          '<div ng-transclude="child1"></div>'+
       '</div>',   
        link:function(scope, elem, attrs){
          
        }  
    }
}]);
app.directive('childElem2',[function(){
    return {
        restrict: 'AE',
        replace:true,
        template:'<div>'+
                    '<div>這是childElem2指令的內容</div>'+
                 '</div>',   
        link:function(scope, elem, attrs){
          
        }  
    }
}])

app.directive('childElem3',[function(){
    return {
        restrict: 'AE',
        replace:true,
        template:'<div>'+
                    '<div>這是childElem3指令的內容</div>'+
                 '</div>',   
        link:function(scope, elem, attrs){
          
        }  
    }
}])
</script>
</html>

謝謝你們的耐心觀看。

相關文章
相關標籤/搜索