在 AngularJS 中使用同位素(ng-repeat)

Posted

技术标签:

【中文标题】在 AngularJS 中使用同位素(ng-repeat)【英文标题】:Using Isotope with AngularJS (ng-repeat) 【发布时间】:2012-08-07 19:27:27 【问题描述】:

我正在尝试使用 angular 加载 div 以提供给同位素进行布局。出于某种原因,我不能使用 ng-repeat 来创建 div。当我做类似的事情时,它工作正常:

[agg.html]

<div class="mygrid" iso-grid>
    <div class="item">myitem</div>
</div>

[controlers.js]

module.directive('isoGrid', function () 
    return function (scope, element, attrs) 
        element.isotope(
            itemSelector: '.item'
        );
    ;
);

module.controller('aggViewport', ['$scope', '$location', function ($scope, $location) 
    $scope.cards = [
        "ID": "myid",
        "class": "cardListTile",
        "badge": "1"
     
        "ID": "myid2",
        "class": "cardListTile",
        "badge": "2"
    ]
]);

虽然上述工作正常,但当我尝试从 Angular 使用 ng-repeat 时,div 似乎变得不可见(它们在 dom 中,但我看不到它们)。我试过调用 isotope('reloadItems') 和 isotope('reLayout'),但似乎没有帮助。

[agg.html]

<div class="mygrid" iso-grid ng-repeat="card in cards">
    <div class="item">myitem</div>
</div>

如何使用 ng-repeat ?

【问题讨论】:

为了避免此类问题,我写了一个原生 AngularJS 等价于 jQuery isotope,随意看看:tristanguigue.github.io/angular-dynamic-layout 【参考方案1】:

尝试 $watching 列表变量(卡片),每当它发生变化时重新应用同位素。我认为您的问题是同位素在填充 ng-repeat 之前正在运行。

快速示例:

scope.$watch(attrs.ngModel, function() 
  elm.isotope();
);

【讨论】:

attrs.ngModel 是什么? 是html中提供的ng-model属性的范围值。请参阅指令定义对象下的 -scope here【参考方案2】:

我使用 masonry 指令 + ng-animate 为进入/离开动画实现了类似的东西,这是一个纯 CSS 动画演示(带有 chrome 供应商前缀的 CSS):

http://jsfiddle.net/g/3SH7a/

指令:

angular.module('app', [])
.directive("masonry", function () 
    var NGREPEAT_SOURCE_RE = '<!-- ngRepeat: ((.*) in ((.*?)( track by (.*))?)) -->';
    return 
        compile: function(element, attrs) 
            // auto add animation to brick element
            var animation = attrs.ngAnimate || "'masonry'";
            var $brick = element.children();
            $brick.attr("ng-animate", animation);

            // generate item selector (exclude leaving items)
            var type = $brick.prop('tagName');
            var itemSelector = type+":not([class$='-leave-active'])";

            return function (scope, element, attrs) 
                var options = angular.extend(
                    itemSelector: itemSelector
                , attrs.masonry);

                // try to infer model from ngRepeat
                if (!options.model)  
                    var ngRepeatMatch = element.html().match(NGREPEAT_SOURCE_RE);
                    if (ngRepeatMatch) 
                        options.model = ngRepeatMatch[4];
                    
                

                // initial animation
                element.addClass('masonry');

                // Wait inside directives to render
                setTimeout(function () 
                    element.masonry(options);

                    element.on("$destroy", function () 
                        element.masonry('destroy')
                    );

                    if (options.model) 
                        scope.$apply(function() 
                            scope.$watchCollection(options.model, function (_new, _old) 
                                if(_new == _old) return;

                                // Wait inside directives to render
                                setTimeout(function () 
                                    element.masonry("reload");
                                );
                            );
                        );
                    
                );
            ;
        
    ;
)

【讨论】:

以上是关于在 AngularJS 中使用同位素(ng-repeat)的主要内容,如果未能解决你的问题,请参考以下文章

Angular / Javascript - 重新加载ng-repeat数据后更改类

为啥同位素会混淆点击 iFrame?

如何使用分页实现同位素

同位素中的元素居中

同位素高度不随内容变化

选中/取消选中同位素中的输入复选框