Ionic v3 Segment - изменение активного сегмента при прокрутке

Недавно мне стало интересно, почему нельзя изменить активный сегмент в ionic v3, изменив [(ngModel)] в ionScroll.subscribe (). У меня есть содержимое сегмента, расположенное друг под другом. Поэтому я использую кнопки для "прокрутки якоря" и хочу, чтобы они отображались наоборот, когда моя позиция прокрутки находится над определенной позицией. Вот мой код:

<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, я вызвал событие click для элемента. Затем сегмент вскоре становится активным, и через миллисекунду предыдущий сегмент снова становится активным. Также я играл с изменением классов CSS. Однако при нажатии на кнопки сегмента я должен был захватить это, удалить все segment-button segment-active классы и добавление его вручную к выбранному.

1 ответ

Решение

Хорошо, так как никто не ответил на мой вопрос, я потратил много времени, пытаясь и исследуя. Здесь мы идем, решение:

Каждое движение прокрутки в ионном приложении оказывается вне угла по соображениям производительности. Так что нельзя делать модификацию угловых переменных или делать content.resize() внутри любого обработчика события прокрутки (ionScroll, ionScrollStart, ionScrollEnd).

Таким образом, вы должны обернуть каждый код в: 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/

Вот полное решение с 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'
  });
}
Другие вопросы по тегам