@@ -38,7 +38,8 @@ import {
3838 Observable ,
3939 of ,
4040 Subject ,
41- Subscription
41+ Subscription ,
42+ timer
4243} from 'rxjs' ;
4344import { debounceTime , filter , map , startWith , switchMap , takeUntil } from 'rxjs/operators' ;
4445import {
@@ -48,20 +49,20 @@ import {
4849 NguCarouselPrevDirective
4950} from './../ngu-carousel.directive' ;
5051import {
52+ Transfrom ,
5153 Breakpoints ,
5254 NguCarouselConfig ,
5355 NguCarouselOutletContext ,
5456 NguCarouselStore
5557} from './ngu-carousel' ;
58+ import { NguWindowScrollListener } from './ngu-window-scroll-listener' ;
5659
57- // @dynamic
5860@Component ( {
5961 selector : 'ngu-carousel' ,
6062 templateUrl : 'ngu-carousel.component.html' ,
6163 styleUrls : [ 'ngu-carousel.component.scss' ] ,
6264 changeDetection : ChangeDetectionStrategy . OnPush
6365} )
64- // @dynamic
6566// eslint-disable-next-line @angular-eslint/component-class-suffix
6667export class NguCarousel < T >
6768 extends NguCarouselStore
@@ -88,7 +89,6 @@ export class NguCarousel<T>
8889 listener1 : ( ) => void ;
8990 listener2 : ( ) => void ;
9091 listener3 : ( ) => void ;
91- listener4 : ( ) => void ;
9292
9393 @Input ( 'dataSource' )
9494 get dataSource ( ) : any {
@@ -147,8 +147,6 @@ export class NguCarousel<T>
147147
148148 private carousel : any ;
149149
150- private onScrolling : any ;
151-
152150 private _hammertime : HammerManager | null = null ;
153151
154152 private _destroy$ = new Subject < void > ( ) ;
@@ -179,7 +177,8 @@ export class NguCarousel<T>
179177 private _differs : IterableDiffers ,
180178 @Inject ( PLATFORM_ID ) private platformId : object ,
181179 private _cdr : ChangeDetectorRef ,
182- private _ngZone : NgZone
180+ private _ngZone : NgZone ,
181+ private _nguWindowScrollListener : NguWindowScrollListener
183182 ) {
184183 super ( ) ;
185184 }
@@ -230,17 +229,21 @@ export class NguCarousel<T>
230229 if ( ! this . arrayChanges ) return ;
231230
232231 this . arrayChanges . forEachOperation (
233- ( item : IterableChangeRecord < any > , adjustedPreviousIndex : number , currentIndex : number ) => {
234- const node = this . _getNodeDef ( data [ currentIndex ] , currentIndex ) ;
232+ (
233+ item : IterableChangeRecord < any > ,
234+ adjustedPreviousIndex : number | null ,
235+ currentIndex : number | null
236+ ) => {
237+ const node = this . _getNodeDef ( data [ currentIndex ! ] , currentIndex ! ) ;
235238
236239 if ( item . previousIndex == null ) {
237- const context = new NguCarouselOutletContext < any > ( data [ currentIndex ] ) ;
238- context . index = currentIndex ;
239- viewContainer . createEmbeddedView ( node . template , context , currentIndex ) ;
240+ const context = new NguCarouselOutletContext < any > ( data [ currentIndex ! ] ) ;
241+ context . index = currentIndex ! ;
242+ viewContainer . createEmbeddedView ( node . template , context , currentIndex ! ) ;
240243 } else if ( currentIndex == null ) {
241- viewContainer . remove ( adjustedPreviousIndex ) ;
244+ viewContainer . remove ( adjustedPreviousIndex ! ) ;
242245 } else {
243- const view = viewContainer . get ( adjustedPreviousIndex ) ;
246+ const view = viewContainer . get ( adjustedPreviousIndex ! ) ;
244247 viewContainer . move ( view ! , currentIndex ) ;
245248 }
246249 }
@@ -341,9 +344,9 @@ export class NguCarousel<T>
341344 this . onMove . complete ( ) ;
342345
343346 /** remove listeners */
344- clearTimeout ( this . onScrolling ) ;
345- for ( let i = 1 ; i <= 4 ; i ++ ) {
346- const str = `listener${ i } ` ;
347+ for ( let i = 1 ; i <= 3 ; i ++ ) {
348+ // TODO: revisit later.
349+ const str = `listener${ i } ` as 'listener1' | 'listener2' | 'listener3' ;
347350 this [ str ] && this [ str ] ( ) ;
348351 }
349352 }
@@ -644,7 +647,6 @@ export class NguCarousel<T>
644647 ) ;
645648 }
646649
647- // tslint:disable-next-line:no-unused-expression
648650 this . RTL && ! this . vertical . enabled && this . _renderer . addClass ( this . carousel , 'ngurtl' ) ;
649651 this . _createStyleElem ( `${ dism } ${ itemStyle } ` ) ;
650652 this . _storeCarouselData ( ) ;
@@ -653,7 +655,6 @@ export class NguCarousel<T>
653655 /** logic to scroll the carousel step 1 */
654656 private _carouselScrollOne ( Btn : number ) : void {
655657 let itemSpeed = this . speed ;
656- let translateXval = 0 ;
657658 let currentSlide = 0 ;
658659 let touchMove = Math . ceil ( this . dexVal / this . itemWidth ) ;
659660 touchMove = isFinite ( touchMove ) ? touchMove : 0 ;
@@ -670,7 +671,7 @@ export class NguCarousel<T>
670671 itemSpeed = 400 ;
671672 this . _btnBoolean ( 0 , 1 ) ;
672673 } else if ( this . slideItems >= MoveSlide ) {
673- currentSlide = translateXval = 0 ;
674+ currentSlide = 0 ;
674675 this . _btnBoolean ( 1 , 0 ) ;
675676 } else {
676677 this . _btnBoolean ( 0 , 0 ) ;
@@ -690,7 +691,7 @@ export class NguCarousel<T>
690691 currentSlide = this . dataSource . length - this . items ;
691692 this . _btnBoolean ( 0 , 1 ) ;
692693 } else if ( this . isLast ) {
693- currentSlide = translateXval = 0 ;
694+ currentSlide = 0 ;
694695 itemSpeed = 400 ;
695696 this . _btnBoolean ( 1 , 0 ) ;
696697 } else {
@@ -708,8 +709,6 @@ export class NguCarousel<T>
708709
709710 /** logic to scroll the carousel step 2 */
710711 private _carouselScrollTwo ( Btn : number , currentSlide : number , itemSpeed : number ) : void {
711- // tslint:disable-next-line:no-unused-expression
712-
713712 if ( this . dexVal !== 0 ) {
714713 const val = Math . abs ( this . touch . velocity ) ;
715714 let somt = Math . floor ( ( this . dexVal / val / this . dexVal ) * ( this . deviceWidth - this . dexVal ) ) ;
@@ -750,15 +749,15 @@ export class NguCarousel<T>
750749 this . isLast = ! ! last ;
751750 }
752751
753- private _transformString ( grid : string , slide : number ) : string {
752+ private _transformString ( grid : keyof Transfrom , slide : number ) : string {
754753 let collect = '' ;
755754 collect += `${ this . styleid } { transform: translate3d(` ;
756755
757756 if ( this . vertical . enabled ) {
758- this . transform [ grid ] = ( this . vertical . height / this . inputs . grid [ grid ] ) * slide ;
757+ this . transform [ grid ] = ( this . vertical . height / this . inputs . grid [ grid ] ! ) * slide ;
759758 collect += `0, -${ this . transform [ grid ] } px, 0` ;
760759 } else {
761- this . transform [ grid ] = ( 100 / this . inputs . grid [ grid ] ) * slide ;
760+ this . transform [ grid ] = ( 100 / this . inputs . grid [ grid ] ! ) * slide ;
762761 collect += `${ this . directionSym } ${ this . transform [ grid ] } %, 0, 0` ;
763762 }
764763 collect += `); }` ;
@@ -808,12 +807,18 @@ export class NguCarousel<T>
808807 private _carouselInterval ( ) : void {
809808 const container = this . carouselMain1 . nativeElement ;
810809 if ( this . interval && this . loop ) {
811- this . listener4 = this . _renderer . listen ( 'window' , 'scroll' , ( ) => {
812- clearTimeout ( this . onScrolling ) ;
813- this . onScrolling = setTimeout ( ( ) => {
814- this . _onWindowScrolling ( ) ;
815- } , 600 ) ;
816- } ) ;
810+ this . _nguWindowScrollListener
811+ . pipe (
812+ // Note: do not use `debounceTime` since it may flush queued actions within the Angular zone.
813+ switchMap ( ( ) => timer ( 600 ) ) ,
814+ takeUntil ( this . _destroy$ )
815+ )
816+ . subscribe ( ( ) => {
817+ // Note: we don't run change detection on each `scroll` event, but we re-enter the
818+ // Angular zone once the DOM timer fires to be backwards compatible.
819+ // TODO: revisit later since we may not run change detection at all on this task.
820+ this . _ngZone . run ( ( ) => this . _onWindowScrolling ( ) ) ;
821+ } ) ;
817822
818823 const mapToZero = map ( ( ) => 0 ) ;
819824 const mapToOne = map ( ( ) => 1 ) ;
0 commit comments