Skip to content

Commit 5c205f1

Browse files
committed
refactor(carousel): for use with IntersectionService providedIn root
1 parent de08ca8 commit 5c205f1

File tree

1 file changed

+25
-19
lines changed

1 file changed

+25
-19
lines changed

projects/coreui-angular/src/lib/carousel/carousel/carousel.component.ts

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
import {
22
AfterContentInit,
33
Component,
4+
DestroyRef,
45
ElementRef,
56
EventEmitter,
67
HostBinding,
8+
inject,
79
Inject,
810
Input,
911
OnDestroy,
1012
OnInit,
1113
Output
1214
} from '@angular/core';
13-
import { fromEvent, Subscription, withLatestFrom, zipWith } from 'rxjs';
15+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
16+
import { finalize, fromEvent, Subscription, withLatestFrom, zipWith } from 'rxjs';
1417

1518
import { IntersectionService } from '../../services/intersection.service';
1619
import { IListenersConfig, ListenersService } from '../../services/listeners.service';
@@ -24,7 +27,7 @@ import { Triggers } from '../../coreui.types';
2427
selector: 'c-carousel',
2528
template: '<ng-content></ng-content>',
2629
styleUrls: ['./carousel.component.scss'],
27-
providers: [CarouselService, CarouselState, CarouselConfig, IntersectionService, ListenersService],
30+
providers: [CarouselService, CarouselState, CarouselConfig, ListenersService],
2831
standalone: true
2932
})
3033
export class CarouselComponent implements OnInit, OnDestroy, AfterContentInit {
@@ -93,11 +96,10 @@ export class CarouselComponent implements OnInit, OnDestroy, AfterContentInit {
9396
};
9497
}
9598

96-
private carouselIndexSubscription?: Subscription;
9799
private timerId!: any;
98-
private intersectingSubscription?: Subscription;
99100
private activeItemInterval = 0;
100101
private swipeSubscription?: Subscription;
102+
readonly #destroyRef = inject(DestroyRef);
101103

102104
constructor(
103105
@Inject(CarouselConfig) private config: CarouselConfig,
@@ -116,13 +118,10 @@ export class CarouselComponent implements OnInit, OnDestroy, AfterContentInit {
116118

117119
ngOnDestroy(): void {
118120
this.clearListeners();
119-
this.carouselStateSubscribe(false);
120-
this.intersectionServiceSubscribe(false);
121121
this.swipeSubscribe(false);
122122
}
123123

124124
ngAfterContentInit(): void {
125-
this.intersectionService.createIntersectionObserver(this.hostElement);
126125
this.intersectionServiceSubscribe();
127126
this.carouselState.state = { activeItemIndex: this.activeIndex, animate: this.animate };
128127
this.setListeners();
@@ -172,30 +171,34 @@ export class CarouselComponent implements OnInit, OnDestroy, AfterContentInit {
172171
clearTimeout(this.timerId);
173172
}
174173

175-
private carouselStateSubscribe(subscribe: boolean = true): void {
176-
if (subscribe) {
177-
this.carouselIndexSubscription = this.carouselService.carouselIndex$.subscribe((nextItem) => {
174+
private carouselStateSubscribe(): void {
175+
this.carouselService.carouselIndex$
176+
.pipe(
177+
takeUntilDestroyed(this.#destroyRef)
178+
)
179+
.subscribe((nextItem) => {
178180
if ('active' in nextItem) {
179181
this.itemChange.emit(nextItem.active);
180182
}
181183
this.activeItemInterval = typeof nextItem.interval === 'number' && nextItem.interval > -1 ? nextItem.interval : this.interval;
182184
const isLastItem = ((nextItem.active === nextItem.lastItemIndex) && this.direction === 'next') || ((nextItem.active === 0) && this.direction === 'prev');
183185
!this.wrap && isLastItem ? this.resetTimer() : this.setTimer();
184186
});
185-
} else {
186-
this.carouselIndexSubscription?.unsubscribe();
187-
}
188187
}
189188

190189
private intersectionServiceSubscribe(subscribe: boolean = true): void {
191-
if (subscribe) {
192-
this.intersectingSubscription = this.intersectionService.intersecting$.subscribe(isIntersecting => {
190+
this.intersectionService.createIntersectionObserver(this.hostElement);
191+
this.intersectionService.intersecting$
192+
.pipe(
193+
finalize(() => {
194+
this.intersectionService.unobserve(this.hostElement);
195+
}),
196+
takeUntilDestroyed(this.#destroyRef)
197+
)
198+
.subscribe(isIntersecting => {
193199
this.visible = isIntersecting;
194200
isIntersecting ? this.setTimer() : this.resetTimer();
195201
});
196-
} else {
197-
this.intersectingSubscription?.unsubscribe();
198-
}
199202
}
200203

201204
private swipeSubscribe(subscribe: boolean = true): void {
@@ -204,7 +207,10 @@ export class CarouselComponent implements OnInit, OnDestroy, AfterContentInit {
204207
const touchStart$ = fromEvent<TouchEvent>(carouselElement, 'touchstart');
205208
const touchEnd$ = fromEvent<TouchEvent>(carouselElement, 'touchend');
206209
const touchMove$ = fromEvent<TouchEvent>(carouselElement, 'touchmove');
207-
this.swipeSubscription = touchStart$.pipe(zipWith(touchEnd$.pipe(withLatestFrom(touchMove$))))
210+
this.swipeSubscription = touchStart$.pipe(
211+
zipWith(touchEnd$.pipe(withLatestFrom(touchMove$))),
212+
takeUntilDestroyed(this.#destroyRef)
213+
)
208214
.subscribe(([touchstart, [touchend, touchmove]]) => {
209215
touchstart.stopPropagation();
210216
touchmove.stopPropagation();

0 commit comments

Comments
 (0)