Skip to content

Commit

Permalink
fix(angular): virtual mode run changeDetecton inside ngZone (#4601)
Browse files Browse the repository at this point in the history
  • Loading branch information
vltansky committed May 23, 2021
1 parent 58efa79 commit 4f37a61
Show file tree
Hide file tree
Showing 10 changed files with 366 additions and 286 deletions.
182 changes: 1 addition & 181 deletions playground/angular/src/app/app.component.html
Original file line number Diff line number Diff line change
@@ -1,181 +1 @@
<main>
<div>
<swiper
#swiperVirtualRef
[slidesPerView]="3"
[spaceBetween]="50"
[pagination]="{ type: 'fraction' }"
[virtual]="true"
slideActiveClass="swiper-active whyWouldIuseCustomClass"
[centeredSlides]="true"
navigation
class="mySwiper"
id="mySwiperID"
>
<ng-template swiperSlide *ngFor="let slide of virtualSlides; index as i"
>Slide {{ slide }}</ng-template
>
<ng-template swiperSlide>Slide</ng-template>
<ng-template swiperSlide>Slide</ng-template>
</swiper>

<swiper
#swiperVirtualRef
[slidesPerView]="3"
[spaceBetween]="50"
[pagination]="{ type: 'fraction' }"
[virtual]="true"
[centeredSlides]="true"
navigation
>
<ng-template swiperSlide *ngFor="let slide of slides$ | async; index as i"
>Slide {{ slide }}</ng-template
>
</swiper>
<button (click)="getSlides()">Get slides</button>

<swiper [zoom]="true" [autoplay]="true">
<ng-template swiperSlide class="custom-class" [zoom]="true">
<img src="https://swiperjs.com/demos/images/nature-1.jpg" />
</ng-template>
<ng-template swiperSlide>
<img src="https://swiperjs.com/demos/images/nature-2.jpg" />
</ng-template>
<ng-template swiperSlide [zoom]="true">
<img src="https://swiperjs.com/demos/images/nature-3.jpg" />
</ng-template>
</swiper>

<h3>Custom pagination</h3>
<swiper
#swiperRef
[navigation]="navigation"
(swiper)="log('swiper')"
(slideChange)="log('slideChange')"
[slidesPerView]="3"
[spaceBetween]="50"
[breakpoints]="breakpoints"
[scrollbar]="scrollbar"
[loop]="true"
[(index)]="indexNumber"
[pagination]="{ el: '.swiper-pagination.pagination-test' }"
>
<ng-container *ngIf="show">
<ng-template swiperSlide>Best slide ever 1 {{ show }}</ng-template>
<ng-template swiperSlide>Best slide ever 2</ng-template>
</ng-container>
<ng-template swiperSlide>
<div *ngIf="true">Best slide ever 3</div>
</ng-template>
<ng-template swiperSlide let-data *ngFor="let slide of slides; index as i">
{{ slide }} / active: {{ data.isActive }} / next: {{ data.isNext }}</ng-template
>
<div slot="container-end" class="swiper-pagination pagination-test"></div>
</swiper>
<button (click)="slides.push('test')">Add slide</button>
<button (click)="toggleNavigation()">Toggle navigation</button>
<button (click)="toggleScrollbar()">Toggle scrollbar</button>
<button (click)="breakpointChange()">Breakpoint change</button>
<button (click)="show = !show">Toggle show</button>
<button (click)="indexNumber = 0">0</button>
<button (click)="indexNumber = 3">3</button>
<button (click)="indexNumber = 5">5</button>
<button (click)="indexNumber = 6">6</button>
{{ indexNumber }}

<swiper [config]="exampleConfig">
<ng-template swiperSlide>Best slide ever 2</ng-template>
<ng-template swiperSlide>Best slide ever 2</ng-template>
<ng-template swiperSlide>Best slide ever 2</ng-template>
<ng-template swiperSlide>Best slide ever 2</ng-template>
<ng-template swiperSlide>Best slide ever 2</ng-template>
</swiper>
<button (click)="exampleConfig = { slidesPerView: 2 }">changeConfig</button>

{{ exampleConfig | json }}
</div>
<div>
<swiper
#swiper
[slidesPerView]="1"
[centeredSlides]="true"
[navigation]="{ prevEl: prevEl, nextEl: nextEl }"
[pagination]="pagination"
>
<ng-template swiperSlide *ngFor="let slide of slides2; index as i">
{{ i }} - {{ slide }}
</ng-template>
</swiper>
<button type="button" #nextEl class="swiper-navigation-prev">&lt;</button>
<button type="button" #prevEl class="swiper-navigation-next">&gt;</button>
<hr />
<button (click)="replaceSlides()">replace slides</button>
<button (click)="togglePagination()">Toggle pagination</button>
</div>
<div>
<swiper
[slidesPerView]="1"
[spaceBetween]="50"
[navigation]="true"
[pagination]="{ clickable: true }"
[thumbs]="{ swiper: thumbsSwiper }"
>
<ng-template swiperSlide>Slide 1</ng-template>
<ng-template swiperSlide>Slide 2</ng-template>
<ng-template swiperSlide>Slide 3</ng-template>
<ng-template swiperSlide>Slide 4</ng-template>
<ng-template swiperSlide>Slide 5</ng-template>
<ng-template swiperSlide>Slide 6</ng-template>
</swiper>
<swiper
[slidesPerView]="3"
[spaceBetween]="50"
(swiper)="setThumbsSwiper($event)"
[navigation]="{}"
[pagination]="{ clickable: true }"
[scrollbar]="{ draggable: true }"
[watchSlidesVisibility]="true"
[watchSlidesProgress]="true"
>
<ng-template swiperSlide>Slide 1</ng-template>
<ng-template swiperSlide>Slide 2</ng-template>
<ng-template swiperSlide>Slide 3</ng-template>
<ng-template swiperSlide>Slide 4</ng-template>
<ng-template swiperSlide>Slide 5</ng-template>
<ng-template swiperSlide>Slide 6</ng-template>
</swiper>
</div>
<div>
<swiper
[slidesPerView]="1"
[spaceBetween]="50"
[navigation]="true"
[pagination]="{ clickable: true }"
[controller]="{ control: controlledSwiper }"
>
<ng-template swiperSlide>Slide 1</ng-template>
<ng-template swiperSlide>Slide 2</ng-template>
<ng-template swiperSlide>Slide 3</ng-template>
<ng-template swiperSlide>Slide 4</ng-template>
<ng-template swiperSlide>Slide 5</ng-template>
<ng-template swiperSlide>Slide 6</ng-template>
</swiper>
<swiper
[slidesPerView]="3"
[spaceBetween]="50"
(swiper)="setControlledSwiper($event)"
[navigation]="{}"
[pagination]="{ clickable: true }"
[scrollbar]="{ draggable: true }"
[watchSlidesVisibility]="true"
[watchSlidesProgress]="true"
>
<ng-template swiperSlide>Slide 1</ng-template>
<ng-template swiperSlide>Slide 2</ng-template>
<ng-template swiperSlide>Slide 3</ng-template>
<ng-template swiperSlide>Slide 4</ng-template>
<ng-template swiperSlide>Slide 5</ng-template>
<ng-template swiperSlide>Slide 6</ng-template>
</swiper>
</div>
</main>
<router-outlet></router-outlet>
104 changes: 2 additions & 102 deletions playground/angular/src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,108 +1,8 @@
import { ChangeDetectorRef, Component, ViewChild } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { SwiperComponent } from 'src/angular/src/public-api';
import SwiperCore, {
Navigation,
Pagination,
Scrollbar,
A11y,
Virtual,
Zoom,
Autoplay,
Thumbs,
Controller,
} from '../../../../build/core';

SwiperCore.use([
Navigation,
Pagination,
Scrollbar,
A11y,
Virtual,
Zoom,
Autoplay,
Thumbs,
Controller,
]);
import { Component } from '@angular/core';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
@ViewChild('swiperRef', { static: false }) swiperRef?: SwiperComponent;

show: boolean;
thumbs: any;
slides$ = new BehaviorSubject<string[]>(['']);
constructor(private cd: ChangeDetectorRef) {}
ngOnInit() {}

getSlides() {
this.slides$.next(Array.from({ length: 600 }).map((el, index) => `Slide ${index + 1}`));
}

thumbsSwiper: any;
setThumbsSwiper(swiper) {
this.thumbsSwiper = swiper;
}
controlledSwiper: any;
setControlledSwiper(swiper) {
this.controlledSwiper = swiper;
}

indexNumber = 1;
exampleConfig = { slidesPerView: 3 };
slidesPerView: number = 4;
pagination: any = false;

slides2 = ['slide 1', 'slide 2', 'slide 3'];
replaceSlides() {
this.slides2 = ['foo', 'bar'];
}

togglePagination() {
if (!this.pagination) {
this.pagination = { type: 'fraction' };
} else {
this.pagination = false;
}
}

navigation = false;
toggleNavigation() {
this.navigation = !this.navigation;
}

scrollbar: any = false;
toggleScrollbar() {
if (!this.scrollbar) {
this.scrollbar = { draggable: true };
} else {
this.scrollbar = false;
}
}
breakpoints = {
640: { slidesPerView: 2, spaceBetween: 20 },
768: { slidesPerView: 4, spaceBetween: 40 },
1024: { slidesPerView: 4, spaceBetween: 50 },
};

slides = Array.from({ length: 5 }).map((el, index) => `Slide ${index + 1}`);
virtualSlides = Array.from({ length: 600 }).map((el, index) => `Slide ${index + 1}`);

log(string) {
// console.log(string);
}

breakPointsToggle: boolean;
breakpointChange() {
this.breakPointsToggle = !this.breakPointsToggle;
this.breakpoints = {
640: { slidesPerView: 2, spaceBetween: 20 },
768: { slidesPerView: 4, spaceBetween: 40 },
1024: { slidesPerView: this.breakPointsToggle ? 7 : 5, spaceBetween: 50 },
};
}
}
export class AppComponent {}
18 changes: 16 additions & 2 deletions playground/angular/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,29 @@ import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { SwiperModule } from 'src/angular/src/public-api';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { RouterModule } from '@angular/router';

@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule.withServerTransition({ appId: 'serverApp' }),
SwiperModule,
BrowserAnimationsModule,
RouterModule.forRoot([
{
path: '',
redirectTo: 'home',
pathMatch: 'full',
},
{
path: 'home',
loadChildren: () => import('./home/home.module').then((m) => m.HomeModule),
},
{
path: 'details',
loadChildren: () => import('./detail/detail.module').then((m) => m.DetailModule),
},
]),
],
providers: [],
bootstrap: [AppComponent],
Expand Down
5 changes: 5 additions & 0 deletions playground/angular/src/app/detail/detail.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<button routerLink="..">back</button>

<div>
<img *ngIf="id$ | async as id" src="https://picsum.photos/id/{{ id }}/200" />
</div>
12 changes: 12 additions & 0 deletions playground/angular/src/app/detail/detail.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Component } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { map } from 'rxjs/operators';

@Component({
selector: 'app-details',
templateUrl: './detail.component.html',
})
export class DetailPage {
readonly id$ = this.route.paramMap.pipe(map((params) => params.get('id')));
constructor(private readonly route: ActivatedRoute) {}
}
15 changes: 15 additions & 0 deletions playground/angular/src/app/detail/detail.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule, Routes } from '@angular/router';
import { DetailPage } from './detail.component';
const routes: Routes = [
{
path: '',
component: DetailPage,
},
];
@NgModule({
imports: [CommonModule, RouterModule.forChild(routes)],
declarations: [DetailPage],
})
export class DetailModule {}
Loading

0 comments on commit 4f37a61

Please sign in to comment.