mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-16 18:17:31 +08:00
fix(all): component reusage (#18963)
Use new stencil APIs to allow ionic elements to be reused once removed from the DOM. fixes #18843 fixes #17344 fixes #16453 fixes #15879 fixes #15788 fixes #15484 fixes #17890 fixes #16364
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
import { Component, ComponentInterface, Element, Event, EventEmitter, Host, Listen, Method, Prop, Watch, h } from '@stencil/core';
|
||||
import { Component, ComponentInterface, Element, Event, EventEmitter, Host, Method, Prop, Watch, h } from '@stencil/core';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { rIC } from '../../utils/helpers.js';
|
||||
@ -20,8 +20,8 @@ export class Slides implements ComponentInterface {
|
||||
|
||||
private scrollbarEl?: HTMLElement;
|
||||
private paginationEl?: HTMLElement;
|
||||
private didInit = false;
|
||||
|
||||
private swiperReady = false;
|
||||
private mutationO?: MutationObserver;
|
||||
private readySwiper!: (swiper: SwiperInterface) => void;
|
||||
private swiper: Promise<SwiperInterface> = new Promise(resolve => { this.readySwiper = resolve; });
|
||||
|
||||
@ -35,7 +35,7 @@ export class Slides implements ComponentInterface {
|
||||
|
||||
@Watch('options')
|
||||
async optionsChanged() {
|
||||
if (this.didInit) {
|
||||
if (this.swiperReady) {
|
||||
const swiper = await this.getSwiper();
|
||||
Object.assign(swiper.params, this.options);
|
||||
await this.update();
|
||||
@ -132,20 +132,28 @@ export class Slides implements ComponentInterface {
|
||||
*/
|
||||
@Event() ionSlideTouchEnd!: EventEmitter<void>;
|
||||
|
||||
componentDidLoad() {
|
||||
connectedCallback() {
|
||||
const mut = this.mutationO = new MutationObserver(() => {
|
||||
if (this.swiperReady) {
|
||||
this.update();
|
||||
}
|
||||
});
|
||||
mut.observe(this.el, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
});
|
||||
rIC(() => this.initSwiper());
|
||||
}
|
||||
|
||||
async componentDidUnload() {
|
||||
async disconnectedCallback() {
|
||||
if (this.mutationO) {
|
||||
this.mutationO.disconnect();
|
||||
this.mutationO = undefined;
|
||||
}
|
||||
const swiper = await this.getSwiper();
|
||||
swiper.destroy(true, true);
|
||||
}
|
||||
|
||||
@Listen('ionSlideChanged')
|
||||
onSlideChanged() {
|
||||
if (this.didInit) {
|
||||
this.update();
|
||||
}
|
||||
this.swiper = new Promise(resolve => { this.readySwiper = resolve; });
|
||||
this.swiperReady = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -154,7 +162,10 @@ export class Slides implements ComponentInterface {
|
||||
*/
|
||||
@Method()
|
||||
async update() {
|
||||
const swiper = await this.getSwiper();
|
||||
const [swiper] = await Promise.all([
|
||||
this.getSwiper(),
|
||||
waitForSlides(this.el)
|
||||
]);
|
||||
swiper.update();
|
||||
}
|
||||
|
||||
@ -315,8 +326,9 @@ export class Slides implements ComponentInterface {
|
||||
// init swiper core
|
||||
// @ts-ignore
|
||||
const { Swiper } = await import('./swiper/swiper.bundle.js');
|
||||
await waitForSlides(this.el);
|
||||
const swiper = new Swiper(this.el, finalOptions);
|
||||
this.didInit = true;
|
||||
this.swiperReady = true;
|
||||
this.readySwiper(swiper);
|
||||
}
|
||||
|
||||
@ -485,3 +497,9 @@ export class Slides implements ComponentInterface {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const waitForSlides = (el: HTMLElement) => {
|
||||
return Promise.all(
|
||||
Array.from(el.querySelectorAll('ion-slide')).map(s => s.componentOnReady())
|
||||
);
|
||||
};
|
||||
|
Reference in New Issue
Block a user