6

我正在尝试构建一个自定义指令,将其内容重新排列为网格。我想嵌入ng-repeat指令的结果,然后重新排序结果元素。

问题是当我element.children()在链接函数中调用该方法时,我有一个空数组,因为该ng-repeat指令尚未呈现并被解释为注释。

否则,如果指令的内容是“静态的”,则该指令效果很好。

的HTML

<grid n='6'>
    <div ng-repeat="i in [1,2,3]"></div>
</grid>

我的指令只有有趣的代码片段:

app.directive('grid', [function () {
    return {

        restrict: 'E',
        replace: true,
        transclude: true,
        template: "<div ng-transclude></div>",

        link: function (scope, grid, attrs) {

            // With an ngRepeat transcluded, els result in an empty array
            var els = grid.children();

            // ...
    }; 
}]);

我错过了什么?

4

2 回答 2

0

要实现重新排序,您有多种选择:

  1. 操作 DOM。恕我直言,这是最不受欢迎的方式,它不是很棱角分明。
  2. 重新排序ngRepeat链接函数中使用的数组 ([1, 2, 3])。
  3. 使用orderBy过滤器(文档

我创建了一个 plunk 来演示 2 和 3,希望它可以提供帮助。http://plnkr.co/edit/vrgeBoJZiG6WMu4Rk46u?p=preview

于 2013-07-27T02:58:39.383 回答
0

有几种方法可以解决这个问题。正如评论所建议的那样,您将看到的最简单和最常见的解决方案 - 像这样利用$timeout ...

.directive('grid', ['$timeout', function ($timeout) {
    return {
        restrict: 'E',
        replace: true,
        transclude: true,
        template: '<div ng-transclude></div>',
        link: function (scope, grid, attrs) {
            $timeout(function() {
                console.log(grid.children());
            });
        }
    }
}]);

$timeout([fn], [delay], [invokeApply], [Pass]);

[...]

invokeApply- 如果设置为 false,则跳过模型脏检查,否则将在 $apply 块中调用 fn。(默认:真

调用$timeout将强制执行一个$digest循环——所以当你记录孩子时——ng-repeat指令将“完成”。比赛是这里问题的症结所在——因为当我们进入我们的函数ng-repeat时,它仍然在做它的工作。link


您可以解决此问题的另一种方法 - 这当然不太常见 - 但在说明更详细的事件序列方面做得很好,如下......

.directive('grid', [function () {
    return {
        restrict: 'E',
        replace: true,
        transclude: true,
        template: '<div ng-transclude></div>',
        link: function (scope, grid, attrs) {
            scope.$on('repeat-done', function () {
                console.log(grid.children());
            });
        }
    }
}])
.directive('ngRepeat', [function () {
    return {
        restrict: 'A',
        link: function (scope, elem, attrs) {
            if (scope.$last)
                scope.$root.$broadcast('repeat-done');
        }
    };
}]);

在这里,我们不显眼地扩展为在完成时调用一个函数 - 我们可以在我们的函数ng-repeat中订阅这个。$onlink


JSFiddle Link - 展示这两种方法的简单演示

于 2015-10-15T20:02:41.833 回答