2016-12-02 100 views
1

我正在嘗試爲我的Angular 2應用程序創建一個輪播組件。Angular 2 - 當* ngFor在父組件上完成調用功能時

我想傳送帶是通用的,這樣它會支持這兩種情況下:

<myCarousel> 
    <div>first card</div> 
    <div>second card</div> 
    .... 
</myCarousel> 

和更通用

<myCarousel> 
    <myCard *ngFor="let card of cards" [card]="card"></myCard> 
</myCarousel> 

的問題是,轉盤組件需要初始化到在之後運行* ngFor已完成,否則將無法正確顯示。由於數據來自Web服務調用,我無法猜測確切的時間,但是當* ngFor完成時,我需要輪播組件觀察,隱式或顯式地觀察。任何人都可以幫忙嗎?謝謝!如下

<myCard *ngFor="#card in cards; #last=last" [card]="card" [attr.ready]="last ? false : true"></myCard> 

,並在代碼上的ngFor最後一次嘗試

回答

0

還有另一個#1回答已經解決了這個問題: https://stackoverflow.com/a/36750875/463893

我的解決方法是非常相似的:一個指令(稱爲CarouselItem)應用於* ngFor裏面的轉盤元素,定義一個布爾輸入它告訴元素是否是最後一個元素,以及一個屬性(或eventemitter),可以設置爲一個函數在最後一個元素到達時調用。

所以模板變爲:

<myCarousel #carousel> 
    <myCard *ngFor="let card of cards; let l = last" 
      [card]="card" 
      CarouselItem 
      [ready]="l ? true : false" 
      [init]="carousel.initialize"> 
    </myCard> 
</myCarousel> 

可變#carousel是需要能夠從myCard指令([INIT] = 「carousel.initialize」)引用該傳送帶組件。

以下是該指令代碼:

@Directive({ 
    selector: `[CarouselItem]` 
}) 
export class CarouselItem { 

    @Input('init') onInit: Function =() => {}; 

    @Input() set ready(isReady: boolean) { 
     if (isReady) 
     setTimeout(()=>this.onInit(), 200); 
    }; 
} 

最後轉盤組件包含一個公共初始化方法。

public initialize=()=> { 
    // perform initialisation 
}; 
1

火災事件做到這一點

@Input() 
set ready(isReady: boolean) { 
    if (isReady) someCallbackMethod(); 
} 

希望這有助於:)

+0

謝謝,但你能更清楚一點嗎? 在哪個組件中定義了ready屬性?我試圖在傳送帶組件上定義它,但我似乎無法引用它。 這是我試過,擾亂模板編譯:) udik

1

你可以使用ContentChildren

@ContentChildren(MyCardComponent) cards: QueryList<MyCardComponent>; 

ngOnAfterContentInit() { 
    this.cards 
     .changes 
     //.debounce(100) /* maybe add an additional debounce time.. */ 
     .subscribe(cards => { 
     // received new cards.. 
    }); 
} 
+0

不,我不認爲這會起作用,因爲我希望卡片是完全通用的 - 它可以是MyCard或MyPicture或其他任何東西。否則,我最終會得到一個與某種特定類型的內容緊密綁定的輪播組件。 – udik

相關問題