Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ionic 2 page change event

I want to execute some code every time the page changes.

I could add add an ngOnDestroy method to every page. It appears that I could use Ionic 2 page lifecycle hooks (e.g. ionViewDidUnload) for the exact same effect, but I haven't bothered to test that.I would rather add a single method to the main app class.

I see that you can subscribe to Angular 2 Router events. How do I translate that for use in Ionic 2? I'm getting an error with import { Router } from '@angular/router; in the first place:

TypeScript error: <path>/node_modules/@angular/router/src/common_router_providers.d.ts(9,55): Error TS2305: Module '"<path>/node_modules/@angular/core/index"' has no exported member 'NgModuleFactoryLoader'.
TypeScript error: <path>/node_modules/@angular/router/src/router.d.ts(14,39): Error TS2305: Module '"<path>/node_modules/@angular/core/index"' has no exported member 'NgModuleFactoryLoader'.
TypeScript error: <path>/node_modules/@angular/router/src/router_module.d.ts(9,10): Error TS2305: Module '"<path>/node_modules/@angular/core/index"' has no exported member 'ModuleWithProviders'.

webpack config

var path = require('path');


module.exports = {
  entry: [
    path.normalize('es6-shim/es6-shim.min'),
    'reflect-metadata',
    path.normalize('zone.js/dist/zone'),
    path.resolve('app/app.ts')
  ],
  output: {
    path: path.resolve('www/build/js'),
    filename: 'app.bundle.js',
    pathinfo: false // show module paths in the bundle, handy for debugging
  },
  module: {
    loaders: [
      {
        test: /\.ts$/,
        loader: 'awesome-typescript',
        query: {
          doTypeCheck: true,
          resolveGlobs: false,
          externals: ['typings/browser.d.ts']
        },
        include: path.resolve('app'),
        exclude: /node_modules/
      }
    ],
    noParse: [
      /es6-shim/,
      /reflect-metadata/,
      /zone\.js(\/|\\)dist(\/|\\)zone/
    ]
  },
  resolve: {
    alias: {
      'angular2': path.resolve('node_modules/angular2')
    },
    extensions: ["", ".js", ".ts"]
  }
};

It would make more sense to me anyways if there is a way to use the Nav or NavController service from ionic-angular. Is there a way to do that?

like image 661
jmilloy Avatar asked Oct 03 '16 16:10

jmilloy


People also ask

How do I redirect to another page in ionic?

to​ A redirect route, redirects "from" a URL "to" another URL. This property is that "to" URL. When the defined ion-route-redirect rule matches, the router will redirect to the path specified in this property.

What is ionViewDidEnter?

ionViewDidEnter — Fired after entering (also if it's come back from stack) ionViewWillLeave — Fired if the page will leaved (also if it's keep in stack) ionViewDidLeave — Fired after the page was leaved (also if it's keep in stack) ionViewWillUnload — In Angular not firing because here you have to use ngOnDestroy.

What is event in Ionic?

Events is a publish-subscribe style event system for sending and responding to application-level events across your app.

How do you destroy components in ionic?

Alternatively, You can use ngOnDestroy and ngOnInit of your parent page, but make sure they are called when you suppose them to be called (Ionic stack pages instead of destroying them and calls ngOnDestroy only if that page is on the top of stack and is then removed from the stack, otherwise it uses it's additional ...


3 Answers

Ionic2 doesn't use Angular2's Router. They have their own implementation NavController.


I see that you can subscribe to Angular 2 Router events. How do I translate that for use in Ionic 2?

You can merge all the NavController Events and subscribe to it.

allEvents = Observable.merge(
                 this.navController.viewDidLoad, 
                 this.navController.viewWillEnter, 
                 this.navController.viewDidEnter, 
                 this.navController.viewWillLeave, 
                 this.navController.viewDidLeave, 
                 this.navController.viewWillUnload);

allEvents.subscribe((e) => {
    console.log(e);
});
like image 145
Ankit Singh Avatar answered Sep 24 '22 20:09

Ankit Singh


Another option would be to create a super class where you can use the ionViewDidUnload method (or any other lifecycle hook) like this:

import { Events } from 'ionic-angular';

export class BasePage {

  constructor(public eventsCtrl: Events) { }

  ionViewDidEnter() {
    this.eventsCtrl.publish('page:load');   
  }

  ionViewDidUnload() {
    this.eventsCtrl.publish('page:unload');   
  }
}

Then in every page you just need to extend that BasePage

@Component({
  templateUrl: 'build/pages/my-page/my-page.html',
})
export class MyPage extends BasePage {

constructor(private platform: Platform,
              private nav: NavController, 
              private menuCtrl: MenuController,
              ...,
              eventsCtrl: Events) //notice that this one does not have the private/public keyword 
  {    

    // Due to an issue in angular, by now you must send the dependency to the super class
    // https://github.com/angular/angular/issues/5155
    super(eventsCtrl);

    //...
}

And then, you can add a method like this one in the main app.ts file to respond to those events:

  private initializeEventHandlers() {

    this.events.subscribe('page:load', () => {
      // your code...
    });

    this.events.subscribe('page:unload', () => {
      // your code...
    });

  }
like image 41
sebaferreras Avatar answered Sep 24 '22 20:09

sebaferreras


As of Ionic 3.6, you can use the App component to subscribe to application-wide page change events, as documented in : https://ionicframework.com/docs/api/components/app/App/

For example, if you'd like to track every view change in Google Analytics using the GA cordova plugin, you could amend your app.component.ts like this :

constructor(private app: App, private platform: Platform, private ga: GoogleAnalytics, ...) {
  this.platform.ready().then(() => {
    this.ga.startTrackerWithId('UA-XXX').then(() => {
      this.app.viewDidEnter.subscribe((evt) => {
        // evt.instance is the Ionic page component
        this.ga.trackView(evt.instance.title);
      });
    }).catch(e => console.log('Doh', e));
  }
}
like image 37
jean-baptiste Avatar answered Sep 22 '22 20:09

jean-baptiste