Angular2:HammerJS滑动md-tab-group

时间:2017-03-30 13:00:06

标签: angular typescript angular-material hammer.js

我在 Angular2 webapp中实现了 HammerJS ,我还测试了example代码。此代码使用一个对象数组,似乎完美无缺。但是,我一直在尝试为@ angular2-material / tabs实现相同的系统。因此,我有<md-tab-group><md-tab>个,应该从一个标签到另一个标签。问题是我甚至无法触发滑动功能。

HTML的文件

<md-tab-group md-stretch-tabs [(selectedIndex)]="selectedIndex" (selectedIndexChange)="selectChange()">
      <div class="swipe-box" (swipeleft)="swipe(idx, $event.type)" (swiperight)="swipe(idx, $event.type)">
        <md-tab>
           (...) //Content Tab 1
        </md-tab>
        <md-tab>
           (...) //Content Tab 2
        </md-tab>
      </div>
</md-tab-group>

在示例中可以看到*ngFor*ngFor="let avatar of avatars; let idx=index"类似,用于滑动框 - <div>。但是因为我从<md-tab-group>得到我的索引它似乎不是必要的,即使我包含它,我的事件也没有被触发,但我的<md-tab> - 内容被隐藏了。所以我把它留了出来。我确实在函数中保留了idx参数,因为滑动方法需要一个数字(第二个参数是可选的)。 Documentation

对于TypeScript文件,我实现了以下代码(某些代码可能无法正常工作,但由于无法调用滑动方法,因此无法对其进行测试。)

TS-文件

export class HomeComponent {

  selectedIndex: number = 1;

  selectChange(): void{
    console.log("event triggered INDEX: " + this.selectedIndex);
  }

  SWIPE_ACTION = { LEFT: 'swipeleft', RIGHT: 'swiperight' };

  // Action triggered when user swipes
  swipe(selectedIndex: number, action = this.SWIPE_ACTION.RIGHT) {
    console.log("swiped"); //DOES NOT GET TRIGGERD
    // Out of range
    if (selectedIndex < 0 || selectedIndex > 1 ) return;

    let nextIndex = 0;
    // Swipe right, next tab
    if (action === this.SWIPE_ACTION.RIGHT) {
      const isLast = selectedIndex === 1;
      nextIndex = isLast ? 0 : selectedIndex + 1;
      console.log("swipe right");
    }

    // Swipe left, previous tab
    if (action === this.SWIPE_ACTION.LEFT) {
      const isFirst = selectedIndex === 0;
      nextIndex = isFirst ? 1 : selectedIndex - 1;
      console.log("swipe left");
    }
  }
}

Live demo of what HammerJS does ,是的,我已经实现了index.html中所需的脚本

<!-- Hammer JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.js"></script>

3 个答案:

答案 0 :(得分:8)

我写了一个小指令来完成与你的代码相同的效果:

import { Directive, HostListener, EventEmitter, Input, Output } from '@angular/core';

@Directive({
  selector: '[swipeTab]'
})
export class SwipeTabDirective {

  @HostListener('swipeleft', ['$event'])
  onSwipeleft(event) {
    if(this.selectedIndex + 1 <= this.tabs - 1) {
      this.selectedIndex += 1;
      this.selectedIndexChange.emit(this.selectedIndex);
    }
  }

  @HostListener('swiperight', ['$event'])
  onSwiperight(event) {
    if(this.selectedIndex - 1 >= 0) {
      this.selectedIndex -= 1;
      this.selectedIndexChange.emit(this.selectedIndex);
    }
  }

  @Input() tabs: number;
  @Input()  selectedIndex: number;
  @Output() selectedIndexChange = new EventEmitter<number>();

}

模板应如下所示:

<md-tab-group md-stretch-tabs [(selectedIndex)]="selectedIndex" [(tabs)]="tabs" swipeTab>
       <md-tab>
          (...) //Content Tab 2
       </md-tab>
       <md-tab>
          (...) //Content Tab 2
       </md-tab>
       <md-tab>
          (...) //Content Tab 3
       </md-tab>           
</md-tab-group>

在组件中,您必须声明以下变量:

  selectedIndex: number = 0;
  tabs: number = 3;

玩得开心。

答案 1 :(得分:4)

问题似乎是在错误的<div>中使用了滑动事件。该事件需要在父级 <div>中触发。这是工作代码:

HTML的文件

<div class="md-content" flex md-scroll-y (swipeleft)="swipe(idx, $event.type)" (swiperight)="swipe(idx, $event.type)">
   <md-tab-group md-stretch-tabs [(selectedIndex)]="selectedIndex" (selectedIndexChange)="selectChange()">
           <md-tab>
              (...) //Content Tab 1
           </md-tab>
           <md-tab>
              (...) //Content Tab 2
           </md-tab>
   </md-tab-group>
</div

TS-文件

export class HomeComponent {

  selectedIndex: number = 1;

  selectChange(): void{
    console.log("Selected INDEX: " + this.selectedIndex);
  }

  SWIPE_ACTION = { LEFT: 'swipeleft', RIGHT: 'swiperight' };

  // Action triggered when user swipes
  swipe(selectedIndex: number, action = this.SWIPE_ACTION.RIGHT) {
    // Out of range
    if (this.selectedIndex < 0 || this.selectedIndex > 1 ) return;

    // Swipe left, next tab
    if (action === this.SWIPE_ACTION.LEFT) {
      const isLast = this.selectedIndex === 1;
      this.selectedIndex = isLast ? 0 : this.selectedIndex + 1;
      console.log("Swipe right - INDEX: " + this.selectedIndex);
    }

    // Swipe right, previous tab
    if (action === this.SWIPE_ACTION.RIGHT) {
      const isFirst = this.selectedIndex === 0;
      this.selectedIndex = isFirst ? 1 : this.selectedIndex - 1;
      console.log("Swipe left - INDEX: " + this.selectedIndex);
    }
  }
}

答案 2 :(得分:3)

您需要在每个选项卡上进行滑动检测,而不是容器。

  <div class="swipe-box">
    <md-tab (swipeleft)="swipe(1, $event.type)" 
            (swiperight)="swipe(1, $event.type)">
       (...) //Content Tab 1
    </md-tab>
    <md-tab (swipeleft)="swipe(2, $event.type)" 
            (swiperight)="swipe(2, $event.type)">
       (...) //Content Tab 2
    </md-tab>
  </div>