Ionic 4的可滑动标签在滑动时显示错误

时间:2019-04-11 05:54:20

标签: ionic-framework ionic4

enter image description here在我的角度应用程序中,希望使选项卡可滑动。我在指令中使用指令和模块,我定义了onTabInitialized方法并调用tabs.page.ts,但它不起作用,它给出了错误-> ERROR TypeError :无法读取未定义的属性“ onTabInitialized”。请问如何解决这个问题。

swipe-tab.directive.ts

import { Directive, ElementRef, Output, EventEmitter, OnInit, Renderer2, OnDestroy } from '@angular/core';
import 'hammerjs';

@Directive({
  selector: '[appSwipeTab]'
})
export class SwipeTabDirective implements OnInit, OnDestroy {

  @Output() tabChange = new EventEmitter();

  private currentTabIndex = 0;
  private tabCount = 0;
  private swipeCoords: [number, number];
  private swipeDuration: number;
  private browserSwipeGesture: HammerManager;
  private touchListenersFns = [];
  tabNames: String[] = [];

  constructor(
    public _el: ElementRef,
    private _renderer: Renderer2
  ) {
    console.log('[SwipeTabDirective] constructor');
  }

  ngOnInit() {
    const tabsList = this._el.nativeElement.querySelectorAll('ion-tab-button');

    for (let i = 0, len = tabsList.length; i < len; i += 1) {
      this.tabNames.push(tabsList[i].tab);
    }
    this.tabCount = this.tabNames.length - 1;
    console.log('[SwipeTabDirective] ngOnInit, tabNames: ', this.tabNames);
  }

  onTabInitialized(tabName: string): void {
    console.log('[SwipeTabDirective] onTabInitialized, tabName: ', tabName);

    this.currentTabIndex = this.tabNames.indexOf(tabName);

    const currentTabName = `app-${tabName}`;
    const elem = this._el.nativeElement.querySelectorAll(currentTabName)[0];

    if (!elem) {
      throw new Error('Make sure tab selector has app prefix');
    } else {
      const content = elem.getElementsByTagName('ion-content')[0];

      if (content.querySelector('.swipe-area') === null) {
        console.log('[SwipeTabDirective] adding swipe area');
        this.createWrapperDiv(content);
      }
    }
  }

  createWrapperDiv(content: HTMLElement): void {
    const divElement = this._renderer.createElement('div');
    this._renderer.addClass(divElement, 'swipe-area');
    this._renderer.insertBefore(content, divElement, null);

    while (content.children.length > 1) {
      const child = content.children[0];
      this._renderer.removeChild(content, child);
      this._renderer.appendChild(divElement, child);
    }

    this.addEventListeners(divElement);
  }

  addEventListeners(divElement: HTMLElement) {
    if ('ontouchstart' in document.documentElement) {
      this.touchListenersFns.push(
        this._renderer.listen(divElement, 'touchstart', ($event) => {
          this.deviceSwipeHandler($event, 'start');
        }),
        this._renderer.listen(divElement, 'touchend', ($event) => {
          this.deviceSwipeHandler($event, 'end');
        })
      );
    } else {
      this.browserSwipeGesture = new Hammer(divElement);
      this.browserSwipeGesture.on('swipe', (event) => {
        this.browserSwipeHandler(event);
      });
    }
  }

  deviceSwipeHandler(event: TouchEvent, status: string): void {
    console.log('[SwipeTabDirective] deviceSwipeHandler, status: ', status);
    const coords: [number, number] = [event.changedTouches[0].pageX, event.changedTouches[0].pageY];
    const time = new Date().getTime();

    if (status === 'start') {
      this.swipeCoords = coords;
      this.swipeDuration = time;
    } else if (status === 'end') {
      const direction = [coords[0] - this.swipeCoords[0], coords[1] - this.swipeCoords[1]];
      const duration = time - this.swipeDuration;

      if (duration < 1000 && Math.abs(direction[0]) > 50
        && Math.abs(direction[0]) > Math.abs(direction[1] * 3)) {
        if (direction[0] > 0) {
          this.moveBackward();
        } else {
          this.moveForward();
        }
      }
    }
  }

  browserSwipeHandler(event) {
    console.log('[SwipeTabDirective] browserSwipeHandler, direction: ', event.direction);
    switch (event.direction) {
      case 2:
        this.moveForward();
        break;

      case 4:
        this.moveBackward();
        break;

      default:
        break;
    }
  }

  moveForward(): void {
    console.log('[SwipeTabDirective] moveForward');
    if (this.currentTabIndex < this.tabCount) {
      this.currentTabIndex++;
      this.tabChange.emit(this.tabNames[this.currentTabIndex]);
    }
  }

  moveBackward(): void {
    console.log('[SwipeTabDirective] moveBackward');
    if (this.currentTabIndex > 0) {
      this.currentTabIndex--;
      this.tabChange.emit(this.tabNames[this.currentTabIndex]);
    }
  }

  ngOnDestroy() {
    if (this.touchListenersFns.length > 0) {
      this.touchListenersFns.forEach(fn => fn());
    } else if (this.browserSwipeGesture) {
      this.browserSwipeGesture.off('swipe');
    }
  }

}

还制作了一个模块,用于导出以下代码中所示的指令。

directives.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SwipeTabDirective } from './swipe-tab.directive';

@NgModule({
  declarations: [SwipeTabDirective],
  imports: [
    CommonModule
  ],
  exports: [
    SwipeTabDirective
  ]
})
export class DirectivesModule { }

在tabs.page.ts中使用指令函数,在tabs.page.ts中使用import指令模块

tabs.page.ts

import { Component, ViewChild } from '@angular/core';
import { IonTabs } from '@ionic/angular';
import { SwipeTabDirective } from '../directives/swipe-tab.directive';
@Component({
  selector: 'app-tabs',
  templateUrl: 'tabs.page.html',
  styleUrls: ['tabs.page.scss']
})
export class TabsPage {
  @ViewChild(SwipeTabDirective) swipeTabDirective: SwipeTabDirective;
  @ViewChild('myTabs') tabRef: IonTabs;

  constructor() { }

  ionTabsDidChange($event) {
    console.log('[TabsPage] ionTabsDidChange, $event: ', $event);
    this.swipeTabDirective.onTabInitialized($event.tab);
  }

  onTabChange($event) {
    console.log('[TabsPage] onTabChange, $event: ', $event);
    this.tabRef.select($event);
  }
}

在tabs.page.html中,我定义了两个函数ionTabsDidChange和onTabChange ...

tabs.page.html

<ion-tabs appSwipetab (ionTabsDidChange)="ionTabsDidChange($event)" (tabChange)="onTabChange($event)" #myTabs>

  <ion-tab-bar slot="bottom">
    <ion-tab-button tab="tab1">
      <ion-icon name="flash"></ion-icon>
      <ion-label>Tab One</ion-label>
    </ion-tab-button>

    <ion-tab-button tab="tab2">
      <ion-icon name="apps"></ion-icon>
      <ion-label>Tab Two</ion-label>
    </ion-tab-button>

    <ion-tab-button tab="tab3">
      <ion-icon name="send"></ion-icon>
      <ion-label>Tab Three</ion-label>
    </ion-tab-button>
  </ion-tab-bar>

</ion-tabs>

1 个答案:

答案 0 :(得分:0)

我在 swipe-tab.directive.ts 中做了一些更改 来自

     const currentTabName = `app-${tabName}`;

     const currentTabName = `${tabName}`;

错误消失了。