[Solved] Slides: Accessing a component created within an inner ngFor loop


#1

Hi all,

I have a bit of a conundrum…

I have setup Slides within Slides and need to call the inner slides getActiveIndex(). The number of slides is dynamic. I cannot set a dynamic template variable to use @ViewChild, as this is not allowed.

Any suggestions on how I can access the index of the inner Slides component?

	<ion-slides class="suit-slider" #SuitSlider (ionDidChange)="onSuitChanged()" [options]="suitSliderOptions">

	<ion-slide *ngFor="let suit of deck; let i = index;">

		<ion-slides #CardSlider (ionDidChange)="onCardChanged()" [options]="cardSliderOptions">

			<ion-slide>

				<div class="lrn-card" [style.borderColor]="suit.colour">

					<div class="lrn-card__body" [innerHTML]="suit.body"></div>

				</div>

			</ion-slide>

			<ion-slide *ngFor="let card of suit.cards">

				<div class="lrn-card" [style.borderColor]="suit.colour">
					<h2 class="lrn-card__title">{{card.title}}</h2>
					<div class="lrn-card__body" [innerHTML]="card.body"></div>
				</div>

			</ion-slide>

		</ion-slides>

  </ion-slide>

</ion-slides>

I then access this via:

@ViewChild(‘CardSlider’) cardSlider: Slides;

However, in my example #CardSlider is not unique and is shared by all inner Slides. This means only the first CardSlider’s values are returned in ionDidChange().

I was thinking that I would end up with as follows:

  • Slide 0
    CardSlider0
  • Slide 1
    CardSlider1
  • Slide 2
    CardSlider3

Anyone know of a way to get the unique CardSlider value for each slide? reading up on Ang2 docs, it looks as though @ViewChild is a static attribute and cannot be set dynamically.

It seems like it should be simple… :slight_smile:

Thanks


#2

Right, I found a way. I’d be interested to hear if it is the ‘Angular 2’ way :wink:

I used @ViewChildren

typescript class declaration:
@ViewChildren('CardSlider') cardSliders;

to access the index:

private onCardChanged(){
 // access  the array of card sliders by their _results array index: 0, 1, 2, 3 etc.
  let cardSlider = this.cardSliders._results[this.currentSuitIndex];
  console.log('Card changed', cardSlider.getActiveIndex());
}

This allows me to use #CardSlider as the (static) Template Variable; rather than a single unique ID it seems to create an array of components sharing the same ID, that can be referenced individually via the _results array.


#3

Ok, I found a better way, I think. It still uses @ViewChildren, but now uses Type QueryList and its toArray() function.

Imports:
import { Slides } from 'ionic-angular'; import { ViewChild, ViewChildren, QueryList } from '@angular/core';

Class variable:
@ViewChildren('CardSlider') cardSliders: QueryList<Slides>;

Function:
// called when a card slider changes private onCardChanged(){ let cardsSliderArray = this.cardSliders.toArray(); // safely get QueryList's _results let cardSlider = cardsSliderArray[this.currentSuitIndex]; this.currentCardIndex[this.currentSuitIndex] = cardSlider.getActiveIndex(); console.log('Card changed', cardSlider.getActiveIndex()); }

This works a treat. I now have the ability to access components created within an inner ngFor loop.


#4

I LOVE YOU GUY! Your solution works like a charm