Angular:如何按数组顺序订购NG重复



问题

有没有办法指示Angular通过重复源数据 order> order>?

订购ng-repeat

如果没有,我还能在容器指令的上下文中如何使用ng-repeatorderBy?我用例的详细信息如下。


信息

我有指令包裹任意项目列表的情况。具体而言,绑定到NG重复的数据是较长列表的子阵列。在我的特殊情况下,我有一个指令,该指令包含了使用ng-repeat的另一项指令。例如,

<generic-list-container>
    <youtube-item ng-repeat="video in vm.videos"></youtube-item>
</generic-list-container>

现在假设generic-list-container有一些有关订购其子女列表的特定规则,并且可以接受任何子列表(当然是在理性之内)。

在这种情况下,至少据我了解,我可能不想使用| orderBy: ,因为它将订购逻辑留在了generic-list-container的控制器以外的其他控制器上。为了澄清,generic-list-container的模板不具有具有NG重复,因为这降低了指令的通用性。相反,ng重复在 page 模板中,实际使用了指令。

我实际上具有在指令的控制器逻辑中所需的订购的逻辑,但是我不确定如何给出该信息

理想情况下,有一种方法可以告诉Angular通过数组顺序或数组索引订购,但我不确定在这种情况下如何做。

示例代码

抬头,我要发布此信息以使您对自己的目标有所了解,这不是完整的图片,但我认为代码不需要全部图片。

  function slider() {
    return {
      restrict: 'AE',
      transclude: true,
      templateUrl: 'my-template.html',
      controller: 'SliderCtrl',
      controllerAs: 'vm',
      bindToController: {
        show: '@',
        index: '@',
        scrollBy: '@'
      },
      scope: {},
      link: linkFunc
    };
    function linkFunc($scope, $element, $attrs, ctrl, $transclude) {
      if (angular.isUndefined(ctrl.show)) {
        ctrl.show = 4;
      } else {
        ctrl.show = Math.abs(ctrl.show);
      }
      if (angular.isUndefined(ctrl.index)) {
        ctrl.index = 48;
      } else {
        ctrl.index = Math.abs(ctrl.index);
      }
      if (angular.isUndefined(ctrl.scrollBy)) {
        ctrl.scrollBy = 1;
      } else {
        ctrl.scrollBy = Math.abs(ctrl.scrollBy);
      }
      //wait for ng-repeat to be ready
      var unbind = $scope.$watch('vm.ready', function (newVal, oldVal) {
        if (newVal === true) {
          // active is a subarray of ctrl.items
          ctrl.active = [];
          //find subarray start, end indexes
          var start = ctrl.index + ctrl.show;
          var len = ctrl.items.length;
          //add items to the subarray
          for (var i = ctrl.index; i < start; i++) {
            ctrl.items[i%len].slide.active = true;
            ctrl.active.push(ctrl.items[i % len]);
          }
          //sort the sub array???
          if (start >= len) {
            ctrl.active.sort(function (a, b) {
              return b.index - a.index;
            });
          }
          unbind();
        }
      });
    }

我想您正在创建自定义的角滤波器。这样做很简单。

创建这样的过滤器:

.filter('sortArray', function() {
  return function(array, sortOrder) {
    return array.sort(...add some function here that sorts on sortOrder);
  };
})

然后您可以使用这样的过滤器:

<generic-list-container>
    <youtube-item ng-repeat="video in vm.videos | sortArray : vm.sortKind"></youtube-item>
</generic-list-container>

其中vm.sortKind是可以定义的范围变量。

解决我描述的问题的解决方案是隐藏transcluded, ng-repeat'd列表,在指令模板中,使用自定义的transclude指令来呈现子阵列。详细信息如下。

为Angular UIB项目提供想法的大帽子提示。

示例generic-list-container模板:

<div class="generic-list-container">
    <div class="generic-list-container-content">
        <ol class="generic-list-container-list">
             <!-- render the subarray... -->
            <li ng-repeat="item in subarray" class="generic-list-item">
                <div generic-list-container-transclude="item">
                </div>
            </li>
        </ol>
        <!-- ...and hide the full list -->
        <ol class="generic-list-container-hidden" style="display: none;" ng-transclude>
        </ol>
    </div>
</div>

示例generic-list-container-transclude指令:

  function genericListContainerTransclude() {
    return {
      restrict: 'A',
      require: '^genericListContainer',
      link: linkFunc
    };
    function linkFunc($scope, $element, $attrs) {
      var item = $scope.$eval($attrs.genericListContainerTransclude).item;
      item.$transcludeFn(item.$parent, function (contents) {
        angular.forEach(contents, function (node) {
          $element.append(node);
        });
      });
    }
  }

最终注意:将ng-repeat'D项目包装在指令中,并包括以下行的指示定义:

  $scope.$transcludeFn = transclude;

最新更新