我使用的是Masonry JavaScript网格布局库https://masonry.desandro.com/。使用Angular * ngfor直接从DOM向网格添加新项目时出现问题,如下所示迭代数组:
<div class="grid">
<div class="grid-item grid-item--height{{i}}" *ngFor="let i of array">
{{i}}
</div>
</div>
因为我没有使用&#34;附加的砌体方法&#34;来附加它们,所以砌体不会将它们布局。每次用户向下滚动时,数组都会获得新元素。因此,调用JavaScript方法:
onScrollDown() {
// add another 20 items
this.sum += 20;
for (let i = start; i < this.sum; ++i) {
this.array.push(i); }
}
当数组获得更多元素时,它会自动创建新的html项。所以我需要找到砌成布局的方法,在创建新项目后再次布局它们。在将元素添加到OnScrollMethod中的数组后,我尝试调用$ grid.masonry(&#39; layout&#39;)但它不起作用。 我正在尝试$(&#39; .grid&#39;)。砌体(&#39; reloadItems&#39;),但调用此方法时新项目与之前的项目重叠。
我将不胜感激。
更新
我正在使用我的角度初始化组件方法初始化砌体,如下所示:
ngOnInit() {
this.$grid = jQuery('.grid').masonry({
// options
itemSelector: '.grid-item',
columnWidth: 384,
gutter: 24
});
答案 0 :(得分:1)
自从我必须这么做以来已经很多年了,但基本上是这样:
Masonry运行了很多JS,以便为您正在创建的元素找出最佳的bin-packing。
这意味着它会对每张&#34;卡片上的大量样式信息进行硬编码。在您所在区域内,在计算完之后,它会设置它。
如果你使用砌体添加新的&#34;卡&#34;到那个视图,然后它将继续更新视图,并更改这些卡的布局和大小。
如果您不使用之前使用的砌体实例(使用元素,而不是砌体对象),那么砌体无法跟踪更改。此时,您必须将它们添加到DOM中,然后通过addItems
将其添加到对象,然后调用layout()
(或masonry()
)...或者您有现在,元素已经更新,再次重新编译砌体中的DOM元素。
这可能已经改变,但我对此表示怀疑。
我猜你可以通过编写angular指令来做一些事情,但实现这一目标的便宜而愉快的方法是保存组件元素的实例(或控制器绑定的元素)。 ..无论如何),并保存对您所做的砌体视图的引用,并在更新时,添加所有项目,并再次调用布局... ...或者只是,在每个渲染上,使用您的根元素创建一个新的Masonry视图。 PS:确保一次加载很多新元素,因为如果你一次只加载3个,那就太乱了...... ...另外,请确保预先加载元素中的图像,因为如果图像加载后,您的Masonry布局将变得非常非常混乱。
答案 1 :(得分:1)
已更新
您可以尝试reloadItems
。如果您要加载图片,请使用imagesLoaded.js以避免重叠:
ngOnInit() {
this.$grid = jQuery('.grid').imagesLoaded( function() {
jQuery('.grid').masonry({
// options
itemSelector: '.grid-item',
columnWidth: 384,
gutter: 24
});
});
onScrollDown() {
// add another 20 items
this.sum += 20;
for (let i = start; i < this.sum; ++i) {
this.array.push(i); }
jQuery('.grid').imagesLoaded( function() {
jQuery('.grid').masonry('reloadItems');
});
}
答案 2 :(得分:0)
我在 Vue.js 中使用了 masonry-layout 并且遇到了同样的问题。解决我的问题的方法是:
onScrollDown() {
// ...
// after add another 20 items
this.msnry.reloadItems();
this.msnry.layout();
}
this.msnry 是我的砌体布局实例。