2017-05-06 169 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>