2017-04-25 37 views
1

使用angular2-masonry時,它將以正確的初始順序(即它們在陣列中出現的順序排列ngFor)的順序繪製磚塊,但是當新陣列是從一個訂閱獲得的,它有一個新的項目(甚至只是一個改變的項目),新的/改變的項目總是附加到最後,而不是放置在它的正確位置(它在陣列中的位置)。angular2-masonry總是將項目添加到最後而不是按正確順序

陣列處於訂閱獲得這樣的:

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(); 
      } 
     }); 

此訂閱工作正常,如果我輸出things他們預期,並以正確的順序。出於絕望,我打電話reloadItemslayout石工(從@ViewChild(AngularMasonry) private masonry: AngularMasonry;獲得)。調用成功,沒有錯誤,但項目仍然沒有按照它們在數組中出現的順序繪製。

這裏是我的HTML模板:

<masonry *ngIf="things && things.length" [options]="{ }"> 
     <masonry-brick *ngFor="let thing of things" > 
      Hi, my name is {{thing.name}} 
     </masonry-brick> 
    </masonry> 

再次,要明確 - 在初始加載(通過此相同的訂閱驅動)的項目是正確的順序。

一個附加說明 - 如果我更改(或添加)另一個項目,錯誤地追加到最後的前一個項目現在正確地排序在其正確的位置,並且新項目在結尾(不管是否它應該是或不是)。所以在任何時候,只有一個項目是不合適的。

回答

0

我發現,我可以做此更改磚石電話解決這個問題(特別是把它們放在一個setTimeout調用):

setTimeout(() => { 
    if (this.masonry){ 
     this.masonry._msnry.reloadItems(); 
     this.masonry.layout(); 
    } 
}); 

注意,這兩個電話是必需的。 layout本身不會改變任何東西,reloadItems會最終導致它被正確排序,但有些事件必須先觸發layout

我仍然有興趣瞭解爲什麼。當時我打電話給reloadItemslayout,即使沒有setTimeout,數組已經更新,新的內容應該立即可用於重新加載。

...所以我發佈這個答案,以幫助其他人有同樣的問題,但它仍然是很好的理解實際發生在這裏。

+1

當您運行reloadItems時,View尚未更新。請參閱http://stackoverflow.com/questions/43457149/angular-4-what-is-the-right-way-to-wait-for-operation – yurzui

+0

這真的幫助我學到了一些東西!謝謝。 – WillyC

相關問題