Usando angular2-masonry , dibujará los ladrillos en el orden inicial correcto (es decir, el orden en que aparecen en la matriz para ngFor ), pero cuando se obtiene una nueva matriz de una suscripción y tiene un nuevo elemento (o incluso solo un elemento cambiado), ese elemento nuevo/modificado siempre se agrega al final y no se coloca en su posición correcta (la posición que tiene en la matriz).
Array se obtiene en una suscripción como esta:
this.thingService.getThings().takeUntil(this.unsubscribe) .subscribe( (things:IThing[]) => { this.things = things; /*This should reload and resort the things, but it doesn't.*/ if (this.masonry){ this.debug("yes this is being called"); this.masonry._msnry.reloadItems(); this.masonry.layout(); } }); Esta suscripción funciona correctamente, y si saco things , son como se esperaba y en el orden correcto. Desesperado, estoy llamando a reloadItems y layout en mampostería (obtenido de @ViewChild(AngularMasonry) private masonry: AngularMasonry; ). Las llamadas se realizan correctamente sin errores, pero los elementos aún no se dibujan en el orden en que aparecen en la matriz.
Aquí está mi plantilla HTML:
<masonry *ngIf="things && things.length" [options]="{ }"> <masonry-brick *ngFor="let thing of things" > Hi, my name is {{thing.name}} </masonry-brick> </masonry>Una vez más, para que quede claro: en la carga inicial (impulsada por esta misma suscripción), los artículos están en el orden correcto.
Una nota adicional: si cambio (o agrego) otro elemento más, el elemento anterior que se agregó por error al final ahora se ordena correctamente en su ubicación correcta, y el nuevo elemento se encuentra al final (independientemente de si debería ser o no). no). Entonces, en cualquier momento, solo un elemento está fuera de lugar.
Descubrí que puedo resolver este problema haciendo este cambio en las llamadas de mampostería (específicamente poniéndolas en una llamada setTimeout ):
setTimeout( () => { if (this.masonry){ this.masonry._msnry.reloadItems(); this.masonry.layout(); } }); Tenga en cuenta que ambas llamadas son necesarias. el layout por sí solo no cambia nada y reloadItems hará que eventualmente se ordene correctamente, pero algún evento debe desencadenar un layout primero.
Todavía estoy interesado en entender por qué. En el momento en que llamo a reloadItems y layout , incluso sin setTimeout , la matriz se actualizó y los nuevos contenidos deberían estar disponibles de inmediato para la recarga.
...así que publico esta respuesta para ayudar a cualquier otra persona con el mismo problema, pero aún así sería genial entender lo que realmente está sucediendo aquí.