3

I created a standard nav menu. my home.html has a slider component. this slider component can be navigated using few links that invoke the goToSlide() method exposed using

@ViewChild(Slides) slides: Slides;

As the side navigator menu is implemented and accessible via app.component.ts so how do i get access to slides component defined in home.ts ?

hime.html

<ion-header>
  <ion-navbar no-padding> 
    <button ion-button menuToggle>
      <ion-icon name="menu"></ion-icon>
    </button>
    <ion-title style="background-color:#2298D3">
      <ion-row><ion-col text-left>
      <img (click)="goToSlide(0)" src="assets/images/white_logo_color_background.jpg" width="20%" />
      </ion-col>
      <ion-col text-right>
       <button ion-button clear (click)="goToSlide(1)" style="color:white">Services</button>
       <button ion-button clear (click)="goToSlide(2)" style="color:white">Contact Us</button>
      </ion-col>
      </ion-row>
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content no-padding>
 <ion-slides direction="horizontal" speed="1000" slidesPerView="1" pager="true">
  <ion-slide  class="home-intro" style="background-color:#2298D3;max-height:440px">
  </ion-slide>

  <ion-slide padding class="site-slide" >
     <ion-row>
     <ion-row>
  </ion-slide>
</ion-slides>
</ion-content>

home.ts

import { Component } from '@angular/core';
import { NavController, Slides } from 'ionic-angular';
import { ViewChild } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

import { SendEnquiryService } from '../../providers/send-enquiry.service'

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
   @ViewChild(Slides) slides: Slides;
   slideTwoForm: FormGroup;
  constructor(public navCtrl: NavController,
              public formBuilder: FormBuilder,
              public enquiryService:SendEnquiryService) {
  }

  goToSlide(num){
    this.slides.slideTo(num, 500);
  }

}

app.components.ts:

import { Component, ViewChild } from '@angular/core';
import { Nav, Platform, Slides, Events } from 'ionic-angular';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';

import { HomePage } from '../pages/home/home';
@Component({
  templateUrl: 'app.html'
})
export class MyApp {
   rootPage:any = HomePage;
   @ViewChild(Nav) nav: Nav;

  constructor(platform: Platform, 
              statusBar: StatusBar, 
              splashScreen: SplashScreen,
              public events: Events) {
    platform.ready().then(() => {
      // Okay, so the platform is ready and our plugins are available.
      // Here you can do any higher level native things you might need.
      statusBar.styleDefault();
      splashScreen.hide();
      this.nav.setRoot(HomePage);
    });
  }

  goToSlide(index){
    this.changeCurrentSlide(index);
  }

  changeCurrentSlide(index) {
    this.events.publish('slider:slideTo', index);
  }
}
sebaferreras
  • 44,206
  • 11
  • 116
  • 134
Vik
  • 8,721
  • 27
  • 83
  • 168

2 Answers2

4

You can use Events. In your home.ts file subscribe to an event that will change the current slide:

import { Events } from 'ionic-angular';

@ViewChild(Slides) slides: Slides;

constructor(public events: Events) {
  events.subscribe('slider:slideTo', (index) => {
    if(this.slides) {
      this.slides.slideTo(index, 500);
    } else {
      console.log('Tried to modify the slides but they were not loaded yet');
    }
  });
}

And in your app.component.ts file, just publish that event when needed:

import { Events } from 'ionic-angular';

constructor(public events: Events) {}

changeCurrentSlide(index) {
  this.events.publish('slider:slideTo', index);
}
sebaferreras
  • 44,206
  • 11
  • 116
  • 134
  • 1
    with above logic i get: ERROR TypeError: Cannot read property 'slideTo' of undefined at app.component.ts:25 at events.js:106 at Array.forEach () at Events.publish (events.js:105) at MyApp.webpackJsonp.262.MyApp.changeCurrentSlide (app.component.ts:35) at MyApp.webpackJsonp.262.MyApp.goToSlide (app.component.ts:31) at Object.eval [as handleEvent] (MyApp.html:11) at handleEvent (core.es5.js:11914) at callWithDebugContext (core.es5.js:13206) at Object.debugHandleEvent [as handleEvent] (core.es5.js:12794) – Vik Aug 20 '17 at 21:06
  • Hmm, seems like the event is being triggered before the slides are loaded. I've added a null check when subscribing to the event. Are you publishing the event before the `home.ts` is loaded? – sebaferreras Aug 21 '17 at 04:19
1

You could just insert a slider component on that page too?

If you want the slider component to be defined only in the app component you could:

1.: emit an event in the home.ts which would be listened to in the app.component.

2.: make a slider.service.ts which you inject in your he component and in your app.component or directly in your slider.component(if it's not third party). The slider service could have a public eventemitter which u'd use or a rxjs Subject. This way you can notify a component from within another component.

S. Robijns
  • 1,529
  • 3
  • 14
  • 17