2017-05-06 172 views
0

我正在爲Angular 1.6創建一個指令,該指令爲表格創建了一個固定標題。我試圖通過克隆表頭並解決此問題來實現此目的。這在我的大多數表格中都可以正常工作。我使用scope:false來保留父範圍,因爲某些頭元素引用了例如排序功能。這也適用。我的問題是我有一個表,它創建基於數組的列,因爲我希望能夠更改列。這些列添加了ng-repeat。當我克隆這個頭部時,ng-repeat不會被克隆。AngularJS:包含ng-repeat的克隆元素

如何克隆包含ng-repeat的元素?

HTML表格:

<table class="proloen-table no-last-border" table-fix-header> 
    <thead class="light-blue-background"> 
    <tr> 
     <th>{{vm.testString}}</th> 
     <th ng-repeat="head in vm.tableHeaders"> 
     <span>{{ head.label | translate }}</span> 
     <sorting sortkey="head.sort" color="'white'" filter="vm.state.sorting"></sorting> 
     </th> 
    </tr> 
    </thead> 
    ... 
</table> 

控制器(帶有controllerAs: 'VM')具有(除其他外):

vm.testString = 'Test'; 
vm.tableHeaders = [{label: 'Column1', sort: 'prop1'}, {label: 'Column2', sort: 'prop2'}]; 

該指令如下:

.directive('tableFixHeader', function ($window, $compile) { 
return { 
    restrict: 'A', 
    scope: false, 
    link: function (scope, element) { 
    var clone; 

    function init() { 
     element.wrap('<div class="fix-table-container"></div>'); 
     clone = element.clone(true); 
     clone.find('tbody').remove().end().addClass('table-header-fixed'); 
     clone.removeAttr('table-fix-header'); 
     $compile(clone)(scope); 
     element.before(clone); 
     resizeFixed(); 
    } 
    function resizeFixed() {   
     clone.find('th').each(function (index) { 
     $(this).css('width', element.find('th').eq(index).outerWidth() + 'px'); 
     }); 
    } 
    function scrollFixed() { 
     var offset = $($window).scrollTop(), 
     tableOffsetTop = element.offset().top, 
     tableOffsetBottom = tableOffsetTop + element.height() - element.find('thead').height(); 
     if (offset < tableOffsetTop || offset > tableOffsetBottom){ 
     clone.hide(); 
     } 
     else if (offset >= tableOffsetTop && offset <= tableOffsetBottom && clone.is(':hidden')) { 
     clone.show(); 
     } 
    } 

    $window.addEventListener('scroll', scrollFixed); 
    $window.addEventListener('resize', resizeFixed); 

    scope.$on('$destroy', function() { 
     $window.removeEventListener('scroll', scrollFixed); 
     $window.removeEventListener('resize', resizeFixed); 
    }); 

    init(); 
    } 
}; 
}); 

該指令適用於表格列固定,上面的例子克隆第一個「硬編碼」列就好了,沿着變量來自控制器。克隆ng-repeat時出現問題。我似乎無法弄清楚如何克隆ng-repeat,以便在更新列的列表時能夠工作和更新。

+0

使用超時(等待NG-重複加載第一)。 ** $ timeout(function(){ \t \t \t \t init(); }); ** – VVijay

回答

0

ng-repeat完成渲染時,您可以嘗試使用$scope.$emit發送事件。或創建自己的事件發射器並連接您的指令;

app.directive('onFinishRepeat', function(){ 

    return { 
     restrict: 'A', 
     link: function($scope) { 

      if($scope.$last == true) { 
       $scope.$emit('ng-repeat', 'finish'); 
      } 

     } 

    } 

}) 

app.directive('tableFixHeader', function ($window, $compile) { 
return { 
    restrict: 'A', 
    scope: false, 
    link: function (scope, element) { 
    var clone; 

    function init() { 
     element.wrap('<div class="fix-table-container"></div>'); 
     clone = element.clone(true); 
     clone.find('tbody').remove().end().addClass('table-header-fixed'); 
     clone.removeAttr('table-fix-header'); 
     $compile(clone)(scope); 
     element.before(clone); 
     resizeFixed(); 
    } 
    function resizeFixed() {   
     clone.find('th').each(function (index) { 
     $(this).css('width', element.find('th').eq(index).outerWidth() + 'px'); 
     }); 
    } 
    function scrollFixed() { 
     var offset = $($window).scrollTop(), 
     tableOffsetTop = element.offset().top, 
     tableOffsetBottom = tableOffsetTop + element.height() - element.find('thead').height(); 
     if (offset < tableOffsetTop || offset > tableOffsetBottom){ 
     clone.hide(); 
     } 
     else if (offset >= tableOffsetTop && offset <= tableOffsetBottom && clone.is(':hidden')) { 
     clone.show(); 
     } 
    } 

    $window.addEventListener('scroll', scrollFixed); 
    $window.addEventListener('resize', resizeFixed); 

    scope.$on('$destroy', function() { 
     $window.removeEventListener('scroll', scrollFixed); 
     $window.removeEventListener('resize', resizeFixed); 
    }); 

    $scope.on('ng-repeat', function(event, data){ 

     if(data == 'finish') { 

      init(); 

     } 

    }) 
    } 
}; 
}); 

HTML

<table class="proloen-table no-last-border" table-fix-header> 
<thead class="light-blue-background"> 
<tr> 
    <th>{{vm.testString}}</th> 
    <th ng-repeat="head in vm.tableHeaders" on-finish-repeat> 
    <span>{{ head.label | translate }}</span> 
    <sorting sortkey="head.sort" color="'white'" filter="vm.state.sorting"></sorting> 
    </th> 
</tr> 
</thead> 
... 
</table>