Angular 2 - when *ngFor completes call function on parent component

风流意气都作罢 提交于 2021-02-08 07:51:53

问题


I am trying to create a carousel component for my Angular 2 application.

I want the carousel to be generic, so that it will support both these cases:

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

and the more generic

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

The problem is that the carousel component requires an initialisation to run after the *ngFor has completed, otherwise it won't be displayed correctly.

Since the data is coming from a web service call, I can't guess the exact timing, but I need the carousel component to observe, implicitly or explicitly, when *ngFor has completed. Can anybody help? Thank you!


回答1:


Fire event on last attempt of ngFor as below

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

and in code do this

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

Hope this helps :)




回答2:


You could use ContentChildren.

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

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



回答3:


There is another Stackoverflow answer that already solves the problem: https://stackoverflow.com/a/36750875/463893

My solution is very similar: a directive (called CarouselItem) applied to the carousel elements inside the *ngFor, defining a boolean input that tells whether the element is the last, and a property (or eventemitter) that can be set to a function to call when the last element has been reached.

So the template becomes:

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

the variable #carousel is needed to be able to reference the carousel component from the myCard directive ( [init]="carousel.initialize" ).

The following is the code of the directive:

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

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

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

And finally the carousel component contains a public initialization method.

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


来源:https://stackoverflow.com/questions/40930435/angular-2-when-ngfor-completes-call-function-on-parent-component

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!