Skip to content

Commit ce32217

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

File tree

2 files changed

+37
-22
lines changed

2 files changed

+37
-22
lines changed
Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { ChangeDetectorRef, ElementRef, Renderer2, ViewContainerRef } from '@angular/core';
22
import { IntersectionService, ListenersService } from '../services';
33
import { PopoverDirective } from './popover.directive';
4+
import { TestBed } from '@angular/core/testing';
45

56
describe('PopoverDirective', () => {
67
let document: Document;
@@ -11,8 +12,21 @@ describe('PopoverDirective', () => {
1112

1213
it('should create an instance', () => {
1314
const listenersService = new ListenersService(renderer);
14-
const intersectionService = new IntersectionService();
15-
const directive = new PopoverDirective(document, renderer, hostElement, viewContainerRef, listenersService, changeDetectorRef, intersectionService);
16-
expect(directive).toBeTruthy();
15+
TestBed.configureTestingModule({
16+
providers: [IntersectionService]
17+
});
18+
const intersectionService = TestBed.inject(IntersectionService);
19+
TestBed.runInInjectionContext(() => {
20+
const directive = new PopoverDirective(
21+
document,
22+
renderer,
23+
hostElement,
24+
viewContainerRef,
25+
listenersService,
26+
changeDetectorRef,
27+
intersectionService
28+
);
29+
expect(directive).toBeTruthy();
30+
});
1731
});
1832
});

projects/coreui-angular/src/lib/popover/popover.directive.ts

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ import {
22
AfterViewInit,
33
ChangeDetectorRef,
44
ComponentRef,
5+
DestroyRef,
56
Directive,
67
ElementRef,
78
HostBinding,
9+
inject,
810
Inject,
911
Input,
1012
OnChanges,
@@ -15,9 +17,9 @@ import {
1517
TemplateRef,
1618
ViewContainerRef
1719
} from '@angular/core';
20+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
1821
import { DOCUMENT } from '@angular/common';
19-
import { Subscription } from 'rxjs';
20-
import { debounceTime } from 'rxjs/operators';
22+
import { debounceTime, finalize } from 'rxjs/operators';
2123
import { createPopper, Instance, Options } from '@popperjs/core';
2224

2325
import { Triggers } from '../coreui.types';
@@ -28,7 +30,7 @@ import { IntersectionService } from '../services';
2830
@Directive({
2931
selector: '[cPopover]',
3032
exportAs: 'cPopover',
31-
providers: [ListenersService, IntersectionService],
33+
providers: [ListenersService],
3234
standalone: true
3335
})
3436
export class PopoverDirective implements OnChanges, OnDestroy, OnInit, AfterViewInit {
@@ -96,7 +98,7 @@ export class PopoverDirective implements OnChanges, OnDestroy, OnInit, AfterView
9698
]
9799
};
98100

99-
private intersectingSubscription?: Subscription;
101+
readonly #destroyRef = inject(DestroyRef);
100102

101103
constructor(
102104
@Inject(DOCUMENT) private document: Document,
@@ -109,7 +111,6 @@ export class PopoverDirective implements OnChanges, OnDestroy, OnInit, AfterView
109111
) {}
110112

111113
ngAfterViewInit(): void {
112-
this.intersectionService.createIntersectionObserver(this.hostElement);
113114
this.intersectionServiceSubscribe();
114115
}
115116

@@ -122,7 +123,6 @@ export class PopoverDirective implements OnChanges, OnDestroy, OnInit, AfterView
122123
ngOnDestroy(): void {
123124
this.clearListeners();
124125
this.destroyPopoverElement();
125-
this.intersectionServiceSubscribe(false);
126126
}
127127

128128
ngOnInit(): void {
@@ -154,18 +154,19 @@ export class PopoverDirective implements OnChanges, OnDestroy, OnInit, AfterView
154154
}
155155

156156
private intersectionServiceSubscribe(subscribe: boolean = true): void {
157-
if (subscribe) {
158-
this.intersectingSubscription = this.intersectionService.intersecting$
159-
.pipe(
160-
debounceTime(100)
161-
)
162-
.subscribe(isIntersecting => {
163-
this.visible = isIntersecting ? this.visible : false;
164-
!this.visible && this.removePopoverElement();
165-
});
166-
} else {
167-
this.intersectingSubscription?.unsubscribe();
168-
}
157+
this.intersectionService.createIntersectionObserver(this.hostElement);
158+
this.intersectionService.intersecting$
159+
.pipe(
160+
debounceTime(100),
161+
finalize(() => {
162+
this.intersectionService.unobserve(this.hostElement);
163+
}),
164+
takeUntilDestroyed(this.#destroyRef)
165+
)
166+
.subscribe(isIntersecting => {
167+
this.visible = isIntersecting ? this.visible : false;
168+
!this.visible && this.removePopoverElement();
169+
});
169170
}
170171

171172
private getUID(prefix: string): string {
@@ -241,7 +242,7 @@ export class PopoverDirective implements OnChanges, OnDestroy, OnInit, AfterView
241242
this.popoverRef.instance.id = undefined;
242243
this.changeDetectorRef.markForCheck();
243244
setTimeout(() => {
244-
this.viewContainerRef.detach();
245+
this.viewContainerRef?.detach();
245246
}, 300);
246247
}
247248
}

0 commit comments

Comments
 (0)