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'
});
}