Reputation: 8365
Is it possible to access an element's model from the element?
I'm trying to make a change to the way Ionic's ion slides work. There is a Slides
component and a Slide
component, and usage is like this:
<ion-slides>
<ion-slide> Slide 1 </ion-slide>
<ion-slide> Slide 2 </ion-slide>
</ion-slides>
Each Slide
requires a reference to it's parent Slides
. It's implemented like this:
export var Slide = (function () {
function Slide(elementRef, slides) {
this.slides = slides;
this.ele = elementRef.nativeElement;
this.ele.classList.add('swiper-slide');
slides.rapidUpdate();
}
...
Slide.prototype.ngOnDestroy = function () {
this.slides.rapidUpdate();
};
Slide.decorators = [
{ type: Component, args: [{
selector: 'ion-slide',
template: '<div class="slide-zoom"><ng-content></ng-content></div>',
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
},] },
];
Slide.ctorParameters = [
{ type: ElementRef, },
{ type: Slides, decorators: [{ type: Host },] },
];
Slide.propDecorators = {
'zoom': [{ type: Input },],
};
return Slide;
}());
This means that you can't use an ion-slide
without a ion-slides
parent without getting a template parse error, e.g. in a custom ion-slide
wrapper such as:
@Component({
selector: 'myslide',
template: '<ion-slide> <h1> Test Header </h1> <ng-content></ng-content> </ion-slide>',
})
export class MySlide {
constructor() {}
}
with
<ion-slides>
<myslide> Slide 1 </myslide>
<myslide> Slide 2 </myslide>
</ion-slides>
I'm trying to modify the ionic slides code to allow a Slide
without a Slides
parent by having the Slides
pass a reference to itself to each child Slide
after init. I can easily access the ion-slide
DOM elements that are children of a Slides
component, but how can I access their angular model?
1) During Slides
init, I can select the ion-slides
elements just fine. How can I access the model for these elements? Really, I only need to set the slides
model variable.
Slides.prototype.ngOnInit = function () {
// this query works
var slide_elems = this.getNativeElement().querySelectorAll('ion-slide');
// this obviously doesn't work because
// slides needs to be a attribute of the model,
// not the DOM elem
slide_elems[0].slides = this;
2) @matej-maloča suggested ViewChild
. Really it looks like I need ContentChildren
, so I added a ContentChildren
selector to the Slides
.
Slides.decorators = [
{ type: Component, args: [{
selector: 'ion-slides',
template: '<div class="swiper-container">' +
'<div class="swiper-wrapper">' +
'<ng-content></ng-content>' +
'</div>' +
'<div [class.hide]="!showPager" class="swiper-pagination"></div>' +
'</div>',
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
queries: {
'ionSlides': new ContentChildren(Slide)
},
},] },
];
This almost works. It selects Slide
components that are in the content of the ion-slides
element itself but not ones inside a container component (e.g. the custom myslide
). Is there a way to select those nested ion-slides
elements as well?
<ion-slides>
<-- selected by ContentChildren -->
<ion-slide>Slide 1</ion-slide>
<ion-slide>Slide 2</ion-slide>
<-- the ion-slide within myslide is not selected!! -->
<myslide>Slide 3</myslide>
</ion-slides>
I went looking for a link to the source for ion-slides and found this, which is in typescript. What can I do to update the version I have in my node_modules/ionic-angular to this? Currently everything there is defined in javascript which is a little bit harder to work with.
Upvotes: 1
Views: 1673
Reputation: 974
You need to use ViewChild
.
// it's variable
@ViewChild('ion-slide') elem: any;
In ngOnInit
:
this.elem.nativeElement
See docs for further questions: angular docs
If it doesn't work try to get it with ViewChild on life cycle hook ngAfterViewInit
Upvotes: 3