最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

AngularJS中transclude用法詳解

 更新時間:2016年11月03日 11:20:53   作者:joeylin  
這篇文章主要介紹了AngularJS中transclude用法,詳細分析了transclude的具體功能、使用技巧與相關注意事項,需要的朋友可以參考下

本文實例講述了AngularJS中transclude用法。分享給大家供大家參考,具體如下:

Transclude - 在Angular的指令中,大家會看到有一個這樣的一個配置屬性,這個單詞在英文字典里面也查詢不到真實的意思,所以就用英文來標示它吧。如果你深入的使用angular的話,你就花很大一部分時間來創(chuàng)建自定義指令,那么就不可避免的要深入理解transclude。簡單的講,transclude主要完成以下工作,取出自定義指令中的內容(就是寫在指令里面的子元素),以正確的作用域解析它,然后再放回指令模板中標記的位置(通常是ng-transclude標記的地方),雖然使用內建的ngTransclude對于基本的transclude操作已經(jīng)足夠簡單,但是在文檔中對這個transclude的解釋還是有存在很多疑惑,比如說:

在compile函數(shù)中接收到了一個叫transclude的參數(shù)是什么東西呢?有什么用呢?

在控制器中也有個叫$transclude的可以通過依賴注入的服務,這又是什么呢?

隔離作用域跟transclude有什么關系?

屬性的transclude操作

接下來我們將一個個的解釋:

基本的transclude

我們通過一個基本的transclude例子來講解吧,我們現(xiàn)在要創(chuàng)建的是一個叫buttonBar的指令,用戶可以通過它來添加一組button到頁面上,這個指令會對不同的button進行位置的排列。以下例子css樣式是使用Bootstrap框架。

在fiddle中查看例子:http://jsfiddle.net/ospatil/A969Z/157/

<div ng-controller="parentController">
  <button-bar>
    <button class="primary" ng-click="onPrimary1Click()">{{primary1Label}}</button>
    <button class="primary">Primary2</button>
  </button-bar>
</div>

JS:

var testapp = angular.module('testapp', []);
testapp.controller('parentController', ['$scope', '$window', function($scope, $window) {
  console.log('parentController scope id = ', $scope.$id);
  $scope.primary1Label = 'Prime1';
  $scope.onPrimary1Click = function() {
    $window.alert('Primary1 clicked');
  };
}]);
testapp.directive('primary', function() {
  return {
    restrict: 'C',
    link: function(scope, element, attrs) {
      element.addClass('btn btn-primary');
    }
  }
});
testapp.directive('buttonBar', function() {
  return {
    restrict: 'EA',
    template: '<div class="span4 well clearfix"><div class="pull-right" ng-transclude></div></div>',
    replace: true,
    transclude: true
  };
});

我們先看下HTML標簽,buttonBar指令包裹著幾個button元素。而button元素也被鏈接上了基于class的primary指令,不要太在意這個primary指令的功能它只不過為button元素添加一些css的樣式而已?,F(xiàn)在我們來看buttonBar指令,它提供了一個transclude:true屬性,同時在它的模板里面使用ng-transclude指令。在運行的過程中,Angular獲取到自定義指令的內容,處理完了之后把結果放到了模板中鏈接上ng-transclude的div。

transclude到多個位置

現(xiàn)在我們來增強下我們的buttonBar指令的功能,我們增加了兩種按鈕,primary和secondary,其中primary按鈕是排右邊,secondary是排左邊。所以要做到這個功能,它必須能夠取出指令的內容,然后把它們分別添加到不同的div中,一個用來放primary按鈕, 一個用來放secondary按鈕。

這樣的話,默認的機制已經(jīng)滿足不了我們的要求,于是我們有了另外一種方法:

設置transclude為true

手工移動button元素到合適的div

最后,在指令的編譯或鏈接函數(shù)中移除原始的用來transclude操作的元素

這種方法就是先把所有的內容插入到ng-transclude標記的元素中,然后在link函數(shù)中再找出元素的插入的元素,重新放到元素的其他地方,最后刪除原來暫存內容的元素。

在fiddle中查看例子:http://jsfiddle.net/ospatil/A969Z/158/

<div ng-controller="parentController">
  <button-bar>
    <button class="primary" ng-click="onPrimary1Click()">{{primary1Label}}</button>
    <button class="primary">Primary2</button>
    <button class="secondary">Secondary1</button>
  </button-bar>
</div>

JS:

var testapp = angular.module('testapp', []);
testapp.controller('parentController', ['$scope', '$window',function($scope, $window) {
  $scope.primary1Label = 'Prime1';
  $scope.onPrimary1Click = function() {
    $window.alert('Primary 1 clicked');
  }
}]);
testapp.directive('primary', function() {
  return {
    restrict: 'C',
    link: function(scope, element, attrs) {
      element.addClass('btn btn-primary');
    }
  }
});
testapp.directive('secondary', function() {
  return {
    restrict: 'C',
    link: function(scope, element, attrs) {
      element.addClass('btn');
    }
  }
});
testapp.directive('buttonBar', function() {
  return {
    restrict: 'EA',
    template: '<div class="span4 well clearfix"><div class="primary-block pull-right"></div><div class="secondary-block"></div><div class="transcluded" ng-transclude></div></div>',
    replace: true,
    transclude: true,
    link: function(scope, element, attrs) {
      var primaryBlock = element.find('div.primary-block');
      var secondaryBlock = element.find('div.secondary-block');
      var transcludedBlock = element.find('div.transcluded');
      var transcludedButtons = transcludedBlock.children().filter(':button');
      angular.forEach(transcludedButtons, function(elem) {
        if (angular.element(elem).hasClass('primary')) {
          primaryBlock.append(elem);
        } else if (angular.element(elem).hasClass('secondary')) {
          secondaryBlock.append(elem);
        }
      });
      transcludedBlock.remove();
    }
  };
});

雖然這種方法達到了我們的目的,但是允許默認的transclude操作,然后再人工的從DOM元素中移出不是非常有效率的。因此,我們有了compile函數(shù)中的transclude參數(shù)和控制器中的$transclude服務

編譯函數(shù)參數(shù)中的transclude

開發(fā)者指南中給了我們以下的關于指令中編譯函數(shù)的形式:

function compile(tElement, tAttrs, transclude) { ... }

其中關于第三個參數(shù)transclude的解釋是:

transclude - A transclude linking function: function(scope, cloneLinkingFn).

好的,現(xiàn)在我們利用這個函數(shù)來實現(xiàn)我們剛才講到的功能,從而不需要再先暫存內容,然后再插入到其他地方。

在fiddle中查看例子:http://jsfiddle.net/ospatil/A969Z/161/

<div ng-controller="parentController">
  <button-bar>
    <button class="primary" ng-click="onPrimary1Click()">{{primary1Label}}</button>
    <button class="primary">Primary2</button>
    <button class="secondary">Secondary1</button>
  </button-bar>
</div>

JS:

var testapp = angular.module('testapp', []);
testapp.controller('parentController', ['$scope', '$window', function($scope, $window) {
  $scope.primary1Label = 'Prime1';
  $scope.onPrimary1Click = function() {
    $window.alert('Primary 1 clicked');
  }
}]);
testapp.directive('primary', function() {
  return {
    restrict: 'C',
    link: function(scope, element, attrs) {
      element.addClass('btn btn-primary');
    }
  }
});
testapp.directive('secondary', function() {
  return {
    restrict: 'C',
    link: function(scope, element, attrs) {
      element.addClass('btn');
    }
  }
});
testapp.directive('buttonBar', function() {
  return {
    restrict: 'EA',
    template: '<div class="span4 well clearfix"><div class="primary-block pull-right"></div><div class="secondary-block"></div></div>',
    replace: true,
    transclude: true,
    compile: function(elem, attrs, transcludeFn) {
      return function (scope, element, attrs) {
        transcludeFn(scope, function(clone) {
          var primaryBlock = elem.find('div.primary-block');
          var secondaryBlock = elem.find('div.secondary-block');
          var transcludedButtons = clone.filter(':button');
          angular.forEach(transcludedButtons, function(e) {
            if (angular.element(e).hasClass('primary')) {
              primaryBlock.append(e);
            } else if (angular.element(e).hasClass('secondary')) {
              secondaryBlock.append(e);
            }
          });
        });
      };
    }
  };
});

注意到,transcludeFn函數(shù)需要一個可用的scope作為第一個參數(shù),但是編譯函數(shù)中沒有可用的scope,所以這里需要在鏈接函數(shù)中執(zhí)行transcludeFn。這種方法實際上是在link函數(shù)中同時操作編譯后的DOM元素和模板元素(主要是因為transcludeFn函數(shù)中保存著指令的內容)。

可在控制器中注入的$transclude服務

在開發(fā)者指南中對$transclude服務是這么解釋的:

$transclude - A transclude linking function pre-bound to the correct transclusion scope: function(cloneLinkingFn).

看看如何用在我們的例子中:

在fiddle中查看例子:http://jsfiddle.net/ospatil/A969Z/162/

<div ng-controller="parentController">
  <button-bar>
    <button class="primary" ng-click="onPrimary1Click()">{{primary1Label}}</button>
    <button class="primary">Primary2</button>
    <button class="secondary">Secondary1</button>
  </button-bar>
</div>

JS:

var testapp = angular.module('testapp', []);
testapp.controller('parentController', ['$scope', '$window', function($scope, $window) {
  $scope.onPrimary1Click = function() {
    alert('Primary1 clicked');
  };
  $scope.primary1Label = "Prime1"
}]);
testapp.directive('primary', function() {
  return {
    restrict: 'C',
    link: function(scope, element, attrs) {
      element.addClass('btn btn-primary');
    }
  }
});
testapp.directive('secondary', function() {
  return {
    restrict: 'C',
    link: function(scope, element, attrs) {
      element.addClass('btn');
    }
  }
});
testapp.directive('buttonBar', function() {
  return {
    restrict: 'EA',
    template: '<div class="span4 well clearfix"><div class="primary-block pull-right"></div><div class="secondary-block"></div></div>',
    replace: true,
    transclude: true,
    scope: {},
    controller: ['$scope', '$element', '$transclude', function ($scope, $element, $transclude) {
      $transclude(function(clone) {
        var primaryBlock = $element.find('div.primary-block');
        var secondaryBlock = $element.find('div.secondary-block');
        var transcludedButtons = clone.filter(':button');
        angular.forEach(transcludedButtons, function(e) {
          if (angular.element(e).hasClass('primary')) {
            primaryBlock.append(e);
          } else if (angular.element(e).hasClass('secondary')) {
            secondaryBlock.append(e);
          }
        });
      });
    }],
  };
});

同樣的意思,$transclude中接收的函數(shù)里的參數(shù)含有指令元素的內容,而$element包含編譯后的DOM元素,所以就可以在控制器中同時操作DOM元素和指令內容,跟上文的compile函數(shù)的實現(xiàn)方式有異曲同工之處,這里有幾點需要注意,這個控制器應該是指令的控制器,另一個注意到上文除了第一種方法,其他的地方都沒有用到ng-transclude,因為無需插入到模板中。

Transclude 和 scope

在開發(fā)者指南中提到了a directive isolated scope and transclude scope are siblings,這到底是什么意思呢?假如你認真看前文的例子的話,你就會發(fā)現(xiàn)parentController控制器創(chuàng)建了一個作用域,buttonBar指令在parentController下面創(chuàng)建了一個孤立作用域,而根據(jù)Angular文檔,transclude也創(chuàng)建了另外一個作用域,因此指令的隔離作用域跟transclude作用域是基于同一個父作用域的兄弟作用域。

transclude內容放入元素的屬性

實際上,你不可以這么做,但是你可以通過一種變通的方法來實現(xiàn)這種效果

var testapp = angular.module('testapp', [])
testapp.directive('tag', function() {
 return {
  restrict: 'E',
  template: '<h1><a href="{{transcluded_content}}">{{transcluded_content}}</a></h1>',
  replace: true,
  transclude: true,
  compile: function compile(tElement, tAttrs, transclude) {
    return {
      pre: function(scope) {
        transclude(scope, function(clone) {
         scope.transcluded_content = clone[0].textContent;
        });
      }
    }
  }
 }
});

這里沒有操作DOM元素,只是把元素的文本內容復制給了作用域屬性,然后在通過作用域傳給屬性。

另外要注意的是,這里的clone參數(shù)是jquery或angular.element封裝的整個模板元素。

// todo
add comparing with ng-include

希望本文所述對大家AngularJS程序設計有所幫助。

相關文章

  • 模板視圖和AngularJS之間沖突的解決方法

    模板視圖和AngularJS之間沖突的解決方法

    這篇文章主要介紹了模板視圖和AngularJS之間沖突的解決方法,結合實例形式分析了AngularJS模板視圖沖突的原因并給出了2種解決方法供大家參考使用,需要的朋友可以參考下
    2016-11-11
  • AngularJs的UI組件ui-Bootstrap之Tooltip和Popover

    AngularJs的UI組件ui-Bootstrap之Tooltip和Popover

    這篇文章主要介紹了AngularJs的UI組件ui-Bootstrap之Tooltip和Popover,tooltip和popover是輕量的、可擴展的、用于提示的指令。具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-07-07
  • AngularJS基礎 ng-options 指令詳解

    AngularJS基礎 ng-options 指令詳解

    本文主要介紹AngularJS ng-options 指令,這里對ng-options指令的知識做了詳細整理,并附有詳細的代碼示例,有需要的小伙伴可以參考下
    2016-08-08
  • angularJS?實現(xiàn)長按不觸發(fā)點擊事件可以復制剪貼方法

    angularJS?實現(xiàn)長按不觸發(fā)點擊事件可以復制剪貼方法

    這篇文章主要為大家介紹了angularJS實現(xiàn)長按不觸發(fā)點擊事件可以復制剪貼方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-06-06
  • Angular在一個頁面中使用兩個ng-app的方法(二)

    Angular在一個頁面中使用兩個ng-app的方法(二)

    這篇文章主要介紹了Angular在一個頁面中使用兩個ng-app的方法(二),非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2017-02-02
  • angula中使用iframe點擊后不執(zhí)行變更檢測的問題

    angula中使用iframe點擊后不執(zhí)行變更檢測的問題

    這篇文章主要介紹了angula中使用iframe點擊后不執(zhí)行變更檢測問題,本文給大家分享解決方案,通過實例代碼給的大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-05-05
  • AngularJs 動態(tài)加載模塊和依賴

    AngularJs 動態(tài)加載模塊和依賴

    這篇文章主要介紹了AngularJs 動態(tài)加載模塊和依賴方法的相關資料,需要的朋友可以參考下
    2016-09-09
  • angularJS實現(xiàn)動態(tài)添加,刪除div方法

    angularJS實現(xiàn)動態(tài)添加,刪除div方法

    下面小編就為大家分享一篇angularJS實現(xiàn)動態(tài)添加,刪除div方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-02-02
  • 詳解Angular依賴注入

    詳解Angular依賴注入

    依賴注入(DI -- Dependency Injection)是一種重要的應用設計模式。Angular里面也有自己的DI框架,在設計應用時經(jīng)常會用到它,它可以我們的開發(fā)效率和模塊化程度。&#160;Angular系統(tǒng)中通過在類上添加@Injectable裝飾器來告訴系統(tǒng)這個類(服務)是可注入的。
    2021-05-05
  • AngularJS 執(zhí)行流程詳細介紹

    AngularJS 執(zhí)行流程詳細介紹

    本文詳細介紹了從頁面開始加載到頁面渲染完畢過程中,AngularJS執(zhí)行了哪些操作,有需要的小伙伴可以參考下
    2016-08-08

最新評論

伽师县| 绥中县| 三亚市| 泗阳县| 定陶县| 龙陵县| 施甸县| 万源市| 肃北| 邢台市| 同心县| 宜州市| 大冶市| 枞阳县| 林西县| 仁布县| 泰安市| 滨海县| 伊宁市| 蓬安县| 成武县| 紫阳县| 阳谷县| 基隆市| 双流县| 冀州市| 安福县| 娄烦县| 黄冈市| 平安县| 和平县| 镇康县| 林甸县| 罗山县| 宝鸡市| 肥东县| 永德县| 乌鲁木齐市| 溧阳市| 东阿县| 鄂州市|