首页 文章

离子2页面改变事件

提问于
浏览
20

我想在每次页面更改时执行一些代码 .

我可以添加一个 ngOnDestroy 方法到每个页面 . 似乎我可以使用Ionic 2页面lifecycle hooks(例如 ionViewDidUnload )获得完全相同的效果,但我没有费心去测试它 . 我宁愿在主app类中添加一个方法 .

我看到你可以订阅Angular 2 Router events . 如何翻译用于Ionic 2?我首先得到 import { Router } from '@angular/router; 的错误:

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配置

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"]
  }
};

如果有办法从离子角度使用 NavNavController 服务,那对我来说会更有意义 . 有没有办法做到这一点?

6 回答

  • 5

    Ionic2 不使用 Angular2's Router . 他们有自己的实施 NavController .


    我看到您可以订阅Angular 2路由器事件 . 如何翻译用于Ionic 2?

    您可以合并所有 NavController Events 并订阅它 .

    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);
    });
    
  • 5

    另一个选择是创建一个超类,你可以使用 ionViewDidUnload 方法(或任何其他生命周期钩子),如下所示:

    import { Events } from 'ionic-angular';
    
    export class BasePage {
    
      constructor(public eventsCtrl: Events) { }
    
      ionViewDidEnter() {
        this.eventsCtrl.publish('page:load');   
      }
    
      ionViewDidUnload() {
        this.eventsCtrl.publish('page:unload');   
      }
    }
    

    然后在每个页面中你只需 extend 那个 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);
    
        //...
    }
    

    然后,您可以在主 app.ts 文件中添加类似这样的方法来响应这些事件:

    private initializeEventHandlers() {
    
        this.events.subscribe('page:load', () => {
          // your code...
        });
    
        this.events.subscribe('page:unload', () => {
          // your code...
        });
    
      }
    
  • 11

    从Ionic 3.6开始,您可以使用App组件订阅应用程序范围的页面更改事件,如下所述:https://ionicframework.com/docs/api/components/app/App/

    例如,如果您想使用GA cordova插件跟踪Google Analytics中的每个视图更改,您可以修改app.component.ts,如下所示:

    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));
      }
    }
    
  • 2

    路由器出现在 @angular/router 模块中的第一件事 .

    对于侦听路由更改事件,您可以在路由器 changes 对象上进行订阅 .

    Code

    class MyRouteEventClass {
      constructor(private router: Router) {
         router.changes.subscribe((val) => {
           /* Awesome code here */
         }
        )
      }
    }
    
  • 11

    您可以使用普通的旧Javascript放置在app.component.ts中 . 假设您使用Ionic2-RC0:

    import { Component } from '@angular/core';
    import { Platform } from 'ionic-angular';
    import { StatusBar } from 'ionic-native';
    
    import { YourPage } from '../pages/yourpage/yourpage';
    
    @Component({
      template: `<ion-nav [root]="rootPage"></ion-nav>`
    })
    export class MyApp {
      rootPage = YourPage;
    
      constructor(platform: Platform) {
        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();
          window.addEventListener('load', () =>{
             console.log('page changed');
          });
        });
      }
    

    每次使用NavController更改页面时,您都会在控制台中打印出 page changed .

  • 9

    在Ionic2中,您只需订阅要执行代码的事件,如下所示:

    this.navCtrl.ionViewWillUnload.subscribe(view => {
        console.log(view);
    });
    

    您可以订阅所有Lifecycle Events

相关问题