Search code examples
angularionic-frameworkionic2ionic-view

How can I access the main component's functions from a page navigated to in Ionic 2?


I've created an Ionic v2 application using the following command:

ionic start my-app sidemenu --v2 --ts.

Inside the app.ts file, I have some logic (functions) to do some things (like opening a modal and maintaining state for what the side menu should show). When a certain page (e.g. pages/getting-started/getting-started.ts) is shown, I'd like to reuse the same functions in app.ts. How do I access functions of app.ts from a page navigated to?

My app.ts looks like the following.

class MyApp {
 @ViewChild(Nav) nav:Nav;
 private rootPage:any = GettingStartedPage;
 private pages:any;

 constructor(platform:Platform) {
  this.initializeApp();
  this.pages = { 
   'GettingStartedPage': GettingStartedPage, 
   'AnotherPage': AnotherPage //more pages and modals
  };
 }

 initializeApp() {
  this.platform.ready().then(() => {
   StatusBar.styleDefault();
  });
 }

 openPage(page:string) {
  //when a user clicks on the left menu items, a new page is navigated to
  let component this.pages[page];
  this.nav.setRoot(component);
 }

 openModal(page:string) {
  //modals are opened here, there's more complicated logic
  //but this serves to demonstrate my problem
  let component = this.pages[page];
  Modal.create(component);
 }
}

ionicBootstrap(MyApp);

My getting-started.ts looks like the following.

export class GettingStartedPage {
 constructor(
  platform:Platform, 
  viewController:ViewController,
  navController:NavController,
  navParams:NavParams) {
 }

 buttonClicked() {
  //i need to access app.ts openModal here
  //how do i call a method on app.ts?
  //like MyApp.openModal('SomeModal');
 }
}

Solution

  • With a shared service, you can communicate across the whole application.

    Create a service class like

    @Injectable() 
    class SharedService {
      // use any kind of observable to actively notify about new messages
      someEvent:Subject = new Subject(); 
    }
    

    Provide it on your app

    @App({
      ...
      providers: [SharedService]
    })
    

    Inject it to the App component and any component, directive, or service you want to communicate to the App component from

    constructor(private sharedService:SharedService) {}
    
    someEventHandler() {
      this.sharedService.someEvent.next('some new value');
    }
    

    In the App component subscribe to notifications

    constructor(sharedService:SharedService) {
      sharedService.someEvent.subscribe(event => {
        if(event == ...) {
          this.doSomething();
        }
      });
    }
    

    For details see https://angular.io/docs/ts/latest/cookbook/component-communication.html