在动态追加项目时,砌体不会将它们布局

时间:2017-11-12 23:31:34

标签: javascript html5 angular jquery-masonry masonry

我使用的是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
  });

3 个答案:

答案 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 是我的砌体布局实例。