我一直在玩这个,@ganaraj 的回答非常简洁。如果您$element.masonry('resize');
在他的控制器的appendBrick
方法中添加 a 并考虑图像加载,那么它看起来就可以了。
这是一个 plunker 叉子:http ://plnkr.co/edit/8t41rRnLYfhOF9oAfSUA
这是必要的原因是因为只有在元素上初始化砌体或调整容器大小时才会计算列数,此时我们没有任何砖块,因此它默认为单列。
如果您不想使用“调整大小”方法(我认为它没有记录在案),那么您可以调用 $element.masonry() 但这会导致重新布局,因此您只想在何时调用它添加了第一块砖。
编辑:我已将上面的 plunker 更新为仅resize
在列表长度超过 0 时调用,并且在同一 $digest 周期中移除多个砖块时仅执行一次“重新加载”。
指令代码为:
angular.module('myApp.directives', [])
.directive("masonry", function($parse, $timeout) {
return {
restrict: 'AC',
link: function (scope, elem, attrs) {
elem.masonry({ itemSelector: '.masonry-brick'});
// Opitonal Params, delimited in class name like:
// class="masonry:70;"
//elem.masonry({ itemSelector: '.masonry-item', columnWidth: 140, gutterWidth: $parse(attrs.masonry)(scope) });
},
controller : function($scope,$element){
var bricks = [];
this.appendBrick = function(child, brickId, waitForImage){
function addBrick() {
$element.masonry('appended', child, true);
// If we don't have any bricks then we're going to want to
// resize when we add one.
if (bricks.length === 0) {
// Timeout here to allow for a potential
// masonary timeout when appending (when animating
// from the bottom)
$timeout(function(){
$element.masonry('resize');
}, 2);
}
// Store the brick id
var index = bricks.indexOf(brickId);
if (index === -1) {
bricks.push(brickId);
}
}
if (waitForImage) {
child.imagesLoaded(addBrick);
} else {
addBrick();
}
};
// Removed bricks - we only want to call masonry.reload() once
// if a whole batch of bricks have been removed though so push this
// async.
var willReload = false;
function hasRemovedBrick() {
if (!willReload) {
willReload = true;
$scope.$evalAsync(function(){
willReload = false;
$element.masonry("reload");
});
}
}
this.removeBrick = function(brickId){
hasRemovedBrick();
var index = bricks.indexOf(brickId);
if (index != -1) {
bricks.splice(index,1);
}
};
}
};
})
.directive('masonryBrick', function ($compile) {
return {
restrict: 'AC',
require : '^masonry',
link: function (scope, elem, attrs, MasonryCtrl) {
elem.imagesLoaded(function () {
MasonryCtrl.appendBrick(elem, scope.$id, true);
});
scope.$on("$destroy",function(){
MasonryCtrl.removeBrick(scope.$id);
});
}
};
});