移动由 ng-repeat 创建的 angularJS 元素

Posted

技术标签:

【中文标题】移动由 ng-repeat 创建的 angularJS 元素【英文标题】:Moving angularJS elements created by ng-repeat 【发布时间】:2013-12-07 18:12:50 【问题描述】:

我正在尝试将由 ng-repeat 创建的元素移动到某些列中。我使用指令成功地做到了,但是当我对 ng-repeat 操作的对象数组进行排序时,就会出现问题。搜索最小列然后在其中插入元素的指令无法确定最小列(可能是因为列中仍有元素)。 我相信我使用的结构(指令/控制器等)不是最佳的,我找不到如何组织角度代码来获得我想要的行为。

这是一个 jsFiddle,显示了我现在拥有的内容:http://jsfiddle.net/kytXy/6/ 您可以看到这些项目已正确插入到列中。如果单击重新排列排序的按钮,则不会再次插入它们。如果你多次点击同一个按钮,看看会发生什么...... 我放置了注释警报,您可以取消注释,以便您可以查看项目是如何插入的以及出了什么问题。我还尝试在再次插入之前清空列(在 jsfiddle 中注释了 js),但没有成功。

这里是代码: html

<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<div ng-app="myModule">
    <div ng-controller="Ctrl" >
        <button ng-click="predicate = 'id'; reverse=false; setupColumns()">Sort ID</button>
        <button ng-click="predicate = 'id'; reverse=true; setupColumns()">Sort ID reversed</button>
        <div id="columns" generate-sub-columns post-render>
        </div>
        <div class="elements">
            Elements are stored here !
        <div class="element" ng-repeat="(key,elt) in elts | orderBy:predicate:reverse" id="elementkey">
           Text: elt.a
        </div>
        </div>
    </div>
</div>

JS:

var myModule = angular.module('myModule', []);

myModule.controller('Ctrl', function($scope) 
    $scope.predicate='id';
    $scope.reverse=false;

    $scope.elts = [
        id:0,a:"Hi man !",
        id:1,a:"This is some text",
        id:2,a:"Wanted to say hello.",
        id:3,a:"Hello World!",
        id:4,a:"I love potatoes :)",
        id:5,a:"Don't know what to say now. Maybe I'll just put some long text",
        id:6,a:"Example",
        id:7,a:"Example2",
        id:8,a:"Example3",
        id:9,a:"Example4",
        id:10,a:"Example5",
        id:11,a:"Example6"
    ];

    $scope.setupColumns = function() 
        console.log('calling setupColumns');
        var eltIndex = 0;
        var element = jQuery("#element0");
        /*while(element.length > 0) 
            jQuery('#elements').append(element);
            eltIndex++;
            element = jQuery("#element"+eltIndex);
            alert(1);
        
        alert('Columns should be empty');*/
        element = jQuery("#element0");
        eltIndex = 0;
        var columnCount = 0;
        while (jQuery("#column"+columnCount).size() >0)
            columnCount++;
        while(element.length > 0) 
            console.log('placing new element');
            var smallestColumn = 0;
            var smallestSize = jQuery("#columns").height();
            for (var i = 0; i < columnCount; i++) 
                var columnSize = jQuery(".column#column"+i).height();
                if (columnSize < smallestSize) 
                    smallestColumn = i;
                    smallestSize = columnSize;
                
            ;
            jQuery('.column#column'+smallestColumn).append(element);
            eltIndex++;
            element = jQuery("#element"+eltIndex);
            //alert(1);
        
        //alert('Columns should be filled');
    ;
);

myModule.directive('generateSubColumns', function() 
    return 
        restrict: 'A',
        controller: function() 
            var availableWidth = jQuery("#columns").width();
            var sizePerColumn = 100;
            var nbColumns = Math.floor(availableWidth/sizePerColumn);
            if (nbColumns<=1) 
                nbColumns=1;
            for (var i = 0; i < nbColumns; i++) 
                jQuery('<div class="column" id="column'+i+'">Column '+i+'</div>').appendTo('#columns');
            ;
        
    ;
);

myModule.directive('postRender', [ '$timeout', function($timeout) 
    var def = 
        restrict: 'A', 
        terminal: true,
        transclude: true,
        link: function(scope, element, attrs) 
            $timeout(scope.setupColumns, 0);
        
    ;
    return def;
]);

还有一些 CSS:

#columns 
    width: 100%;


.column 
    width: 100px;
    display:inline-block;
    vertical-align: top;
    border: 1px solid black;


.element 
    border: 1px solid red;

我该如何解决? 提前致谢, 希尔纽斯

【问题讨论】:

【参考方案1】:

首先.. 你为什么要这样做?

var element = jQuery("#element0");

在控制器内部? 这种代码(DOM 操作)应该放在链接函数指令中,并使用$element 参数来访问 DOM 元素。

另外.. 如果你使用column-count 属性来划分你的容器呢? https://developer.mozilla.org/es/docs/Web/CSS/column-count

【讨论】:

以上是关于移动由 ng-repeat 创建的 angularJS 元素的主要内容,如果未能解决你的问题,请参考以下文章

折叠使用 Angular js ng-repeat 和过滤器创建的 div

Angular中的ng-repeat元素之间的差距

Angular JS——将ng-repeat应用于异步添加到DOM的东西

来自 WebApi2 response.data 的 Angular ng-repeat 刷新

Angular 5 ng-repeat 实现

Angular - 无法使 ng-repeat orderBy 工作