desandro / masonry

:love_hotel: Cascading grid layout plugin
https://masonry.desandro.com
16.39k stars 2.11k forks source link

Angular - When appending items dynamically, masonry does not layout them out. #1011

Closed dbayonacode closed 6 years ago

dbayonacode commented 6 years ago

I have an issue when appending new items to the grid directly from the DOM using Angular *ngfor which iterate through an a array as follows:

<div class="grid"> <div class="grid-item grid-item--height{{i}}" *ngFor="let i of array"> {{i}}</div> </div>

Because I am not appending them using the "appended masonry method", masonry does not layout them out. The array is getting new elements every time a user scroll down. So a JavaScript method is called:

onScrollDown() { // add another 20 items this.sum += 20; for (let i = start; i < this.sum; ++i) { this.array.push(i); } } When the array get more elements, it automatically creates new html items. So i need to find the way masonry layout them out again after the new items are being created. I tried calling $grid.masonry('layout'); after the elements have being added to the array in the OnScrollMethod but it did not work. I am trying $('.grid').masonry('reloadItems') as well, but calling this method the new items are overlapping the previous ones.

I am initializing masonry using my angular initialize component method as follows:

ngOnInit() { this.$grid = jQuery('.grid').masonry({ // options itemSelector: '.grid-item', columnWidth: 384, gutter: 24 });

I would appreciate any help.

desandro commented 6 years ago

I'm sorry to see you're having trouble with Masonry. Could you provide a reduced test case? See Submitting Issues in the contributing guidelines.

dbayonacode commented 6 years ago

Thanks @desandro . I had already created a test case in plunker when I was looking for help on stackoverflow; hope it is useful, Test Case: https://plnkr.co/edit/hNReGKNozqmthl6zrYQM?p=preview

desandro commented 6 years ago

Looks like you're using angular masonry. In which case, have you tried using the Angular masonry directive?

dbayonacode commented 6 years ago

I am using for masonry (masonry.desandro.com) and for infinite scrolling: ngx-infinite-scroll. In the test-case u can see the file src/app.ts , the method ngOnInit() is initialising masonry as follows:

jQuery(document).ready(function () { jQuery('.grid').masonry({ // options itemSelector: '.grid-item', columnWidth: 200 }); });

This file (Controller) render a view template as you can see in the same file, as follows:

<div class="search-results" infinite-scroll [infiniteScrollDistance]="2" [infiniteScrollThrottle]="10" (scrolled)="onScrollDown()" [scrollWindow]="true"><div class="grid"> <div class="grid-item grid-item--height{{i}}" *ngFor="let i of array"> {{i}}</div> </div></div>

Each time user scroll down the method onScrollDown() in the same controller is called increasing the size of the array "array" in order the html template can add new items <div class="grid-item">...</div> automatically using the previous binding:

<div class="grid"> <div class="grid-item grid-item--height{{i}}" *ngFor="let i of array"> {{i}}</div> </div>

The items are being added but unfortunately they are being overlapped. I can not find the way to reload the items again properly. I have tried msnry.reloadItems() but without success.

Test Case: https://plnkr.co/edit/hNReGKNozqmthl6zrYQM?p=preview

desandro commented 6 years ago

This sounds like an Angular issue. I'm sorry to say I have no expertise with Angular and I cannot provide any guidance here.

dbayonacode commented 6 years ago

Thanks @desandro . Well I have taken has a recomendation one of your previous questions. So I have change the library. I am using now angular2-masonry, actually a fork of it, called ngx-masonry, which works perfectly with angular > 2. Thanks again.