Ionic v3 Segment - 滚动时更改活动段

Ionic v3 Segment - Change active segment while scrolling

我最近想知道为什么不能通过在 ionScroll.subscribe() 中修改 [(ngModel)] 来更改 ionic v3 中的活动段。我将我的片段内容堆叠在彼此之下。所以我正在使用 "anchor-scrolling" 的按钮,并希望当我的滚动位置超过特定位置时使它们显示反之亦然。这是我的代码:

<ion-segment [(ngModel)]="segData">
  <ion-segment-button (click)="this.scrollToCard('card1')" value="seg1">Card1</ion-segment-button>
  <ion-segment-button (click)="this.scrollToCard('card2')" value="seg2">Card2</ion-segment-button>
</ion-segment>

<div [ngSwitch]="segData">
  <ion-list *ngSwitchCase="'seg1'">
    <ion-item>
      <ion-card #card1>...</ion-card>
    </ion-item>
    <ion-item>
      <ion-card #card2>...</ion-card>
    </ion-item>
  </ion-list>
</div>

example.ts

segData: string;

export class ShowCar
  {
  @ViewChild(Content) content : Content;
  ...
  constructor(...)
    {
    this.segData = "seg1";
    }
  ...
  ionViewDidLoad()
    {  
    //This would work
    //setTimeout( () => { this.segData = "seg2"; }

    //Inside ionScroll.subscribe() it is not working
    //Even if i wrap this into "setTimeout"
    this.content.ionScroll.subscribe( scrollData =>
      {
      if( scrollData.scrollTop > seg1PosFromTop)
        this.segData = "seg2";
      });
    }
  ...
  }

我尝试了很多东西,可能会发生一些疯狂的事情。例如,由于最新的 angular 允许直接使用 DOM 中的元素,我触发了元素上的点击事件。然后该段很快显示为活动状态,并且在一毫秒后,先前的段再次变为活动状态。我也在玩弄 css 类。但是,当单击分段按钮时,我必须捕获它,删除所有 segment-button segment-active 类 并将其手动添加到所选按钮。

好吧,既然没有人回答我的问题,我就花了很多时间尝试和研究。我们开始吧,解决方案:

出于性能原因,离子应用程序中的每个滚动运动恰好在 angular 的 外部 之外。因此不能修改 angular 变量或在任何滚动事件处理程序(ionScrollionScrollStartionScrollEnd)中执行 content.resize()

所以你必须将每个代码包装成:this.zone.run()

import { Component, NgZone } from '@angular/core';
@Component({
  template: `
    <ion-header>
      <ion-navbar>
        <ion-title></ion-title>
      </ion-navbar>
    </ion-header>
    <ion-content (ionScroll)="scrollHandler($event)">
       <p> Some realllllllly long content </p>
    </ion-content>
`})
class E2EPage {
 public scrollAmount = 0;
 constructor( public zone: NgZone){}
 scrollHandler(event) {
   console.log(`ScrollEvent: ${event}`)
   this.zone.run(()=>{
     // since scrollAmount is data-binded,
     // the update needs to happen in zone
     this.scrollAmount++
   })
 }
}

https://ionicframework.com/docs/api/components/content/Content/#advanced

这是 ionic4 的完整解决方案:

// tab.page.html

<ion-header  >
 <!-- Scrollable Segment -->
 <ion-toolbar class="less-height" color="primary">
    <ion-segment scrollable mode="md" (ionChange)="segmentChanged(segment)" [(ngModel)]="segment" >
        <ion-segment-button mode="md" id="seg-1" value="0">
          <p>Description</p>
        </ion-segment-button>
        <ion-segment-button mode="md" id="seg-2" value="1">
          <p>Interconnections</p>
        </ion-segment-button>
        <ion-segment-button mode="md" id="seg-3" value="2">
          <p>Declensions</p>
        </ion-segment-button>
        <ion-segment-button mode="md" id="seg-4" value="3">
          <p>Phraseologisms</p>
        </ion-segment-button>
        <ion-segment-button mode="md" id="seg-5" value="4">
          <p>Etymology</p>
        </ion-segment-button>
        <ion-segment-button mode="md" id="seg-6" value="5">
          <p>Analysis</p>
        </ion-segment-button>
      </ion-segment>
</ion-toolbar>
</ion-header>

<ion-content>
    <ion-slides (ionSlideDidChange)="slideChanged()" class="word-slides">
        <ion-slide>
          <p>Slide 1</p>
        </ion-slide>
        <ion-slide>
          <p>Slide 2</p>
        </ion-slide>
        <ion-slide>
          <p>Slide 3</p>
        </ion-slide>
        <ion-slide>
          <p>Slide 4</p>
        </ion-slide>
        <ion-slide>
          <p>Slide 5</p>
        </ion-slide>
        <ion-slide>
          <p>Slide 6</p>
        </ion-slide>
      </ion-slides>
</ion-content>

// tab.page.ts

 @ViewChild(IonSlides) slider: IonSlides;
  segment = 0;
  constructor() {}
async segmentChanged(event) {
  await this.slider.slideTo(this.segment);
  this.slider.update();
}
async slideChanged() {
  this.segment = await this.slider.getActiveIndex();
  this.focusSegment(this.segment+1);
}

focusSegment(segmentId) {
  document.getElementById('seg-'+segmentId).scrollIntoView({ 
    behavior: 'smooth',
    block: 'center',
    inline: 'center'
  });
}