最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to execute a function every time an ion-tab button gets clicked - Stack Overflow

programmeradmin7浏览0评论

I am trying to build a barcode scanner app with the Ionic framework. The function in scan.page.ts works fine, but unfortunately just once. After I scanned one barcode, the scanner wont open anymore.

I think it might be an issue with the ion-tabs. They only trigger the scan() function once. Afterwards the function will not get executed anymore.

scan.page.ts

import { Component, OnInit } from '@angular/core';
import { BarcodeScanner } from '@ionic-native/barcode-scanner/ngx';
import { DataServiceService } from '../../app/data-service.service';
import { Toast } from '@ionic-native/toast/ngx';
import { Router } from '@angular/router';
import { Platform, AlertController } from '@ionic/angular';
import * as moment from 'moment';

@Component({
  selector: 'app-scan',
  templateUrl: './scan.page.html',
  styleUrls: ['./scan.page.scss'],
})
export class ScanPage implements OnInit {

  productViews: any = {};
  productViewsbyUser: any[] = [];
  isProdcutsAvailable = true;

  selectedProduct: any;
  isCameraOpen = false;
  showScan = false;
  products: any[] = [];
  productFound = true;
  displayUserName: any;

  exitModalDisplayed = false;

  constructor(
    private barcodeScanner: BarcodeScanner,
    private router: Router,
    public platform: Platform,
    private toast: Toast,
    public dataService: DataServiceService,
    public alertCtrl: AlertController) {
    console.log(`Scan Page called`);
    }

  ngOnInit() {

    this.dataService.getProducts()
    .subscribe((response) => {
      this.products = <any[]><unknown>response;
      console.table(this.products);
     });

    this.scan();

    this.handleBackButton();

  }

  getMoment() {
    return moment().milliseconds(0);
  }

// Start scanning procedure
  scan() {
    this.selectedProduct = {};
    this.isCameraOpen = true;
    this.showScan = true;
    this.barcodeScanner.scan().then((barcodeData) => {
      setTimeout(() => {
        this.isCameraOpen = false;
      }, 500);
      if (barcodeData.cancelled) {
        return;
      }
      console.log(`barcodeData`, barcodeData);
      this.selectedProduct = this.products.find(product => product.plu === barcodeData.text);
      if (this.selectedProduct !== undefined) {
        this.selectedProduct.scannedAt = this.getMoment().toISOString();
        // this.selectedProduct.userName = this.displayUserName(); // TO TEST !!!
        this.productFound = true;
        // insert product views with firebase generated based key
        this.dataService.insertProductViewAnalaytics(this.selectedProduct)
          .subscribe(() => {
            console.log(`Product view analytics inserted in Firebase`);
            this.initScanHistoryData();
          });
      } else {
        this.productFound = false;
        this.toast.show(`Product not found`, '5000', 'center').subscribe(
          toast => {
            console.log(toast);
          }
        );
      }
    }, (err) => {
      setTimeout(() => {
        this.isCameraOpen = false;
      }, 1000);
      this.toast.show(err, '5000', 'center').subscribe(
        toast => {
          console.log(toast);
        }
      );
    });
  }

  async initScanHistoryData() {
    this.dataService.getProductViewsForUser()
      .subscribe((response) => {
        this.productViews = response;
        const userProductViews = [];
        // tslint:disable-next-line: forin
        for (const key in this.productViews) {
          userProductViews.push(this.productViews[key]);
        }
          userProductViews.sort(function (a, b) {
            return moment(b.scannedAt).diff(moment(a.scannedAt));

            // ENTER USER NAME HERE???

        });

        this.productViewsbyUser = userProductViews;
        console.log('user productViews ', userProductViews);

        if (this.productViewsbyUser.length) {
          this.isProdcutsAvailable = true;
        } else {
          this.isProdcutsAvailable = false;
        }
        console.log('productViews ', this.productViews);
      });
  }

  handleBackButton() {
    this.platform.backButton.subscribeWithPriority(9999, () => {
      console.log('exit');
      if (this.exitModalDisplayed || this.isCameraOpen) {
        return;
      }
      this.exitModalDisplayed = true;
      const alert = this.alertCtrl.create({
        header: 'Do you want to Exit?',
        // message: 'Do you want Exit?',
        buttons: [
          {
            text: 'Cancel',
            role: 'cancel',
            cssClass: 'secondary',
            handler: () => {
              console.log('Cancel clicked');
              this.exitModalDisplayed = false;
            }
          },
          {
            text: 'Yes',
            handler: () => {
              console.log('Confirm Okay');
              navigator['app'].exitApp();
            }
          }
        ]
      });
      alert.then(x => x.present());
    });
  }
}

tabs.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/mon';
import { FormsModule } from '@angular/forms';
import { Routes, RouterModule } from '@angular/router';

import { IonicModule } from '@ionic/angular';

import { TabsPage } from './tabs.page';

const routes: Routes = [
  {
    path: 'tabs',
    ponent: TabsPage,
    children: [
      { path: 'profile', loadChildren: '../profile/profile.module#ProfilePageModule' },
      { path: 'products', loadChildren: '../products/products.module#ProductsPageModule' },
      { path: 'scan', loadChildren: '../scan/scan.module#ScanPageModule' },
    ]
  },
  {
    path: '',
    redirectTo: '/tabs/products',
    pathMatch: 'full'

  }
];

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    IonicModule,
    RouterModule.forChild(routes)
  ],
  declarations: [TabsPage]
})
export class TabsPageModule {}

tabs.page.html

<ion-tabs>
    <ion-tab-bar slot="bottom">
      <ion-tab-button tab="products">
        <ion-icon name="md-list"></ion-icon>
        <ion-label>Products</ion-label>
        <!-- <ion-badge>6</ion-badge> -->
      </ion-tab-button>

      <ion-tab-button tab="scan">
        <ion-icon name="md-qr-scanner"></ion-icon>
        <ion-label>Scan</ion-label>
      </ion-tab-button>

      <ion-tab-button tab="profile">
        <ion-icon name="md-person"></ion-icon>
        <ion-label>Profile</ion-label>
      </ion-tab-button>

    </ion-tab-bar>
  </ion-tabs>

I expect that the scanner gets opened every time the scan tab button gets pressed.

I am trying to build a barcode scanner app with the Ionic framework. The function in scan.page.ts works fine, but unfortunately just once. After I scanned one barcode, the scanner wont open anymore.

I think it might be an issue with the ion-tabs. They only trigger the scan() function once. Afterwards the function will not get executed anymore.

scan.page.ts

import { Component, OnInit } from '@angular/core';
import { BarcodeScanner } from '@ionic-native/barcode-scanner/ngx';
import { DataServiceService } from '../../app/data-service.service';
import { Toast } from '@ionic-native/toast/ngx';
import { Router } from '@angular/router';
import { Platform, AlertController } from '@ionic/angular';
import * as moment from 'moment';

@Component({
  selector: 'app-scan',
  templateUrl: './scan.page.html',
  styleUrls: ['./scan.page.scss'],
})
export class ScanPage implements OnInit {

  productViews: any = {};
  productViewsbyUser: any[] = [];
  isProdcutsAvailable = true;

  selectedProduct: any;
  isCameraOpen = false;
  showScan = false;
  products: any[] = [];
  productFound = true;
  displayUserName: any;

  exitModalDisplayed = false;

  constructor(
    private barcodeScanner: BarcodeScanner,
    private router: Router,
    public platform: Platform,
    private toast: Toast,
    public dataService: DataServiceService,
    public alertCtrl: AlertController) {
    console.log(`Scan Page called`);
    }

  ngOnInit() {

    this.dataService.getProducts()
    .subscribe((response) => {
      this.products = <any[]><unknown>response;
      console.table(this.products);
     });

    this.scan();

    this.handleBackButton();

  }

  getMoment() {
    return moment().milliseconds(0);
  }

// Start scanning procedure
  scan() {
    this.selectedProduct = {};
    this.isCameraOpen = true;
    this.showScan = true;
    this.barcodeScanner.scan().then((barcodeData) => {
      setTimeout(() => {
        this.isCameraOpen = false;
      }, 500);
      if (barcodeData.cancelled) {
        return;
      }
      console.log(`barcodeData`, barcodeData);
      this.selectedProduct = this.products.find(product => product.plu === barcodeData.text);
      if (this.selectedProduct !== undefined) {
        this.selectedProduct.scannedAt = this.getMoment().toISOString();
        // this.selectedProduct.userName = this.displayUserName(); // TO TEST !!!
        this.productFound = true;
        // insert product views with firebase generated based key
        this.dataService.insertProductViewAnalaytics(this.selectedProduct)
          .subscribe(() => {
            console.log(`Product view analytics inserted in Firebase`);
            this.initScanHistoryData();
          });
      } else {
        this.productFound = false;
        this.toast.show(`Product not found`, '5000', 'center').subscribe(
          toast => {
            console.log(toast);
          }
        );
      }
    }, (err) => {
      setTimeout(() => {
        this.isCameraOpen = false;
      }, 1000);
      this.toast.show(err, '5000', 'center').subscribe(
        toast => {
          console.log(toast);
        }
      );
    });
  }

  async initScanHistoryData() {
    this.dataService.getProductViewsForUser()
      .subscribe((response) => {
        this.productViews = response;
        const userProductViews = [];
        // tslint:disable-next-line: forin
        for (const key in this.productViews) {
          userProductViews.push(this.productViews[key]);
        }
          userProductViews.sort(function (a, b) {
            return moment(b.scannedAt).diff(moment(a.scannedAt));

            // ENTER USER NAME HERE???

        });

        this.productViewsbyUser = userProductViews;
        console.log('user productViews ', userProductViews);

        if (this.productViewsbyUser.length) {
          this.isProdcutsAvailable = true;
        } else {
          this.isProdcutsAvailable = false;
        }
        console.log('productViews ', this.productViews);
      });
  }

  handleBackButton() {
    this.platform.backButton.subscribeWithPriority(9999, () => {
      console.log('exit');
      if (this.exitModalDisplayed || this.isCameraOpen) {
        return;
      }
      this.exitModalDisplayed = true;
      const alert = this.alertCtrl.create({
        header: 'Do you want to Exit?',
        // message: 'Do you want Exit?',
        buttons: [
          {
            text: 'Cancel',
            role: 'cancel',
            cssClass: 'secondary',
            handler: () => {
              console.log('Cancel clicked');
              this.exitModalDisplayed = false;
            }
          },
          {
            text: 'Yes',
            handler: () => {
              console.log('Confirm Okay');
              navigator['app'].exitApp();
            }
          }
        ]
      });
      alert.then(x => x.present());
    });
  }
}

tabs.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/mon';
import { FormsModule } from '@angular/forms';
import { Routes, RouterModule } from '@angular/router';

import { IonicModule } from '@ionic/angular';

import { TabsPage } from './tabs.page';

const routes: Routes = [
  {
    path: 'tabs',
    ponent: TabsPage,
    children: [
      { path: 'profile', loadChildren: '../profile/profile.module#ProfilePageModule' },
      { path: 'products', loadChildren: '../products/products.module#ProductsPageModule' },
      { path: 'scan', loadChildren: '../scan/scan.module#ScanPageModule' },
    ]
  },
  {
    path: '',
    redirectTo: '/tabs/products',
    pathMatch: 'full'

  }
];

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    IonicModule,
    RouterModule.forChild(routes)
  ],
  declarations: [TabsPage]
})
export class TabsPageModule {}

tabs.page.html

<ion-tabs>
    <ion-tab-bar slot="bottom">
      <ion-tab-button tab="products">
        <ion-icon name="md-list"></ion-icon>
        <ion-label>Products</ion-label>
        <!-- <ion-badge>6</ion-badge> -->
      </ion-tab-button>

      <ion-tab-button tab="scan">
        <ion-icon name="md-qr-scanner"></ion-icon>
        <ion-label>Scan</ion-label>
      </ion-tab-button>

      <ion-tab-button tab="profile">
        <ion-icon name="md-person"></ion-icon>
        <ion-label>Profile</ion-label>
      </ion-tab-button>

    </ion-tab-bar>
  </ion-tabs>

I expect that the scanner gets opened every time the scan tab button gets pressed.

Share Improve this question edited Nov 6, 2019 at 8:34 vlntn asked Nov 6, 2019 at 8:20 vlntnvlntn 3708 silver badges24 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 3

try to another methode, that is using ionViewWillEnter() in your target tab, that is solve my problem too

Right now, your scan() function is only executed when ngOnInit() is called.

If you want to execute it every time a user clicks on the tab you can do something like:

<ion-tab-button tab="scan" (click)="scan()">
  <ion-icon name="md-qr-scanner"></ion-icon>
  <ion-label>Scan</ion-label>
</ion-tab-button>
发布评论

评论列表(0)

  1. 暂无评论