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?
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.
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.
Events is a publish-subscribe style event system for sending and responding to application-level events across your app.
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 ...
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);
});
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...
});
}
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));
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With