【问题标题】:AngularJS: Cloning element containing ng-repeatAngularJS:包含 ng-repeat 的克隆元素
【发布时间】:2017-10-05 04:23:15
【问题描述】:

我正在使用 Angular 1.6 创建一个指令,它为表创建一个固定的标题。我试图通过克隆表头并修复它来实现这一点。这在我的大多数表中都可以正常工作。我正在使用 scope: false 来保持父范围,因为某些标题元素引用例如排序功能。这也有效。我的问题是我拥有一个基于数组创建列的表,因为我希望能够更改列。使用 ng-repeat 添加列。当我克隆此标头时,不会克隆 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,以便在我更新列列表时它可以工作和更新。

【问题讨论】:

  • 使用超时(等待 ng-repeat 先加载)。 $timeout(function(){ init(); });

标签: angularjs angularjs-directive angularjs-ng-repeat


【解决方案1】:

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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-03
    • 1970-01-01
    • 1970-01-01
    • 2015-10-18
    • 2014-02-02
    • 1970-01-01
    • 2013-03-03
    相关资源
    最近更新 更多