Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit9ee24fa

Browse files
committed
refactor(dropdown): migrate to contendChild(), and constructor-based dependency injection to inject(), cleanup
1 parent6afaded commit9ee24fa

File tree

1 file changed

+56
-60
lines changed

1 file changed

+56
-60
lines changed

‎projects/coreui-angular/src/lib/dropdown/dropdown/dropdown.component.ts

Lines changed: 56 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
11
import{DOCUMENT}from'@angular/common';
22
import{
3-
AfterContentInit,
43
AfterViewInit,
54
booleanAttribute,
65
ChangeDetectorRef,
76
Component,
87
computed,
9-
ContentChild,
8+
contentChild,
109
DestroyRef,
1110
Directive,
1211
effect,
1312
ElementRef,
1413
forwardRef,
15-
Inject,
1614
inject,
1715
input,
1816
linkedSignal,
@@ -24,7 +22,7 @@ import {
2422
signal,
2523
untracked
2624
}from'@angular/core';
27-
import{Subscription}from'rxjs';
25+
import{takeUntilDestroyed}from'@angular/core/rxjs-interop';
2826
import{filter}from'rxjs/operators';
2927

3028
import{createPopper,Instance,Options,Placement}from'@popperjs/core';
@@ -128,15 +126,16 @@ export class DropdownToggleDirective implements AfterViewInit {
128126
'(click)':'onHostClick($event)'
129127
}
130128
})
131-
exportclassDropdownComponentimplementsAfterContentInit,OnDestroy,OnInit{
132-
constructor(
133-
@Inject(DOCUMENT)privatedocument:Document,
134-
privateelementRef:ElementRef,
135-
privaterenderer:Renderer2,
136-
privatengZone:NgZone,
137-
privatechangeDetectorRef:ChangeDetectorRef,
138-
publicdropdownService:DropdownService
139-
){
129+
exportclassDropdownComponentimplementsOnDestroy,OnInit{
130+
readonly #destroyRef=inject(DestroyRef);
131+
readonly #document=inject(DOCUMENT);
132+
readonly #elementRef=inject(ElementRef);
133+
readonly #renderer=inject(Renderer2);
134+
readonly #ngZone=inject(NgZone);
135+
readonly #changeDetectorRef=inject(ChangeDetectorRef);
136+
readonlydropdownService=inject(DropdownService);
137+
138+
constructor(){
140139
this.dropdownStateSubscribe();
141140
}
142141

@@ -177,7 +176,7 @@ export class DropdownComponent implements AfterContentInit, OnDestroy, OnInit {
177176
*/
178177
readonlypopperOptionsInput=input<Partial<Options>>({},{alias:'popperOptions'});
179178

180-
readonlypopperOptionsEffect=effect(()=>{
179+
readonly#popperOptionsEffect=effect(()=>{
181180
this.popperOptions={ ...untracked(this.#popperOptions), ...this.popperOptionsInput()};
182181
});
183182

@@ -239,7 +238,7 @@ export class DropdownComponent implements AfterContentInit, OnDestroy, OnInit {
239238
computation:(value)=>value
240239
});
241240

242-
readonlyvisibleEffect=effect(()=>{
241+
readonly#visibleEffect=effect(()=>{
243242
constvisible=this.visible();
244243
this.activeTrap=visible;
245244
visible ?this.createPopperInstance() :this.destroyPopperInstance();
@@ -250,13 +249,12 @@ export class DropdownComponent implements AfterContentInit, OnDestroy, OnInit {
250249
readonlyvisibleChange=output<boolean>();
251250

252251
dropdownContext={$implicit:this.visible()};
253-
@ContentChild(DropdownToggleDirective)_toggler!:DropdownToggleDirective;
254-
@ContentChild(DropdownMenuDirective)_menu!:DropdownMenuDirective;
255-
@ContentChild(DropdownMenuDirective,{read:ElementRef})_menuElementRef!:ElementRef;
252+
readonly_toggler=contentChild(DropdownToggleDirective);
253+
readonly_menu=contentChild(DropdownMenuDirective);
254+
readonly_menuElementRef=contentChild(DropdownMenuDirective,{read:ElementRef});
256255

257256
publicactiveTrap=false;
258257

259-
privatedropdownStateSubscription!:Subscription;
260258
privatepopperInstance!:Instance|undefined;
261259
privatelisteners:(()=>void)[]=[];
262260

@@ -283,47 +281,45 @@ export class DropdownComponent implements AfterContentInit, OnDestroy, OnInit {
283281
this.clickedTarget=$event.targetasHTMLElement;
284282
}
285283

286-
dropdownStateSubscribe(subscribe:boolean=true):void{
287-
if(subscribe){
288-
this.dropdownStateSubscription=this.dropdownService.dropdownState$
289-
.pipe(
290-
filter((state)=>{
291-
returnthis===state.dropdown;
292-
})
293-
)
294-
.subscribe((state)=>{
295-
if('visible'instate){
296-
state?.visible==='toggle' ?this.toggleDropdown() :this.visible.set(state.visible);
297-
}
298-
});
299-
}else{
300-
this.dropdownStateSubscription?.unsubscribe();
301-
}
284+
dropdownStateSubscribe():void{
285+
this.dropdownService.dropdownState$
286+
.pipe(
287+
filter((state)=>{
288+
returnthis===state.dropdown;
289+
}),
290+
takeUntilDestroyed(this.#destroyRef)
291+
)
292+
.subscribe((state)=>{
293+
if('visible'instate){
294+
state?.visible==='toggle' ?this.toggleDropdown() :this.visible.set(state.visible);
295+
}
296+
});
302297
}
303298

304299
toggleDropdown():void{
305300
this.visible.update((visible)=>!visible);
306301
}
307302

308303
onClick(event:any):void{
309-
if(!this._toggler?.elementRef.nativeElement.contains(event.target?.closest('[cDropdownToggle]'))){
304+
if(!this._toggler()?.elementRef.nativeElement.contains(event.target?.closest('[cDropdownToggle]'))){
310305
this.toggleDropdown();
311306
}
312307
}
313308

314-
ngAfterContentInit():void{
315-
if(this.variant()==='nav-item'){
316-
this.renderer.addClass(this._toggler.elementRef.nativeElement,'nav-link');
309+
readonly #togglerEffect=effect(()=>{
310+
constvariant=this.variant();
311+
const_toggler=this._toggler();
312+
if(variant==='nav-item'&&_toggler){
313+
this.#renderer.addClass(_toggler.elementRef.nativeElement,'nav-link');
317314
}
318-
}
315+
});
319316

320317
ngOnInit():void{
321318
this.setVisibleState(this.visible());
322319
}
323320

324321
ngOnDestroy():void{
325322
this.clearListeners();
326-
this.dropdownStateSubscribe(false);
327323
this.destroyPopperInstance();
328324
}
329325

@@ -333,22 +329,22 @@ export class DropdownComponent implements AfterContentInit, OnDestroy, OnInit {
333329

334330
// todo: turn off popper in navbar-nav
335331
createPopperInstance():void{
336-
if(this._toggler&&this._menu){
337-
this.ngZone.runOutsideAngular(()=>{
332+
const_toggler=this._toggler();
333+
const_menu=this._menu();
334+
if(_toggler&&_menu){
335+
this.#ngZone.runOutsideAngular(()=>{
338336
// workaround for popper position calculate (see also: dropdown-menu.component)
339-
this._menu.elementRef.nativeElement.style.visibility='hidden';
340-
this._menu.elementRef.nativeElement.style.display='block';
337+
_menu.elementRef.nativeElement.style.visibility='hidden';
338+
_menu.elementRef.nativeElement.style.display='block';
341339
if(this.popper()){
342-
this.popperInstance=createPopper(
343-
this._toggler.elementRef.nativeElement,
344-
this._menu.elementRef.nativeElement,
345-
{ ...this.popperOptions}
346-
);
340+
this.popperInstance=createPopper(_toggler.elementRef.nativeElement,_menu.elementRef.nativeElement,{
341+
...this.popperOptions
342+
});
347343
}
348-
this.ngZone.run(()=>{
344+
this.#ngZone.run(()=>{
349345
this.setListeners();
350-
this.changeDetectorRef.markForCheck();
351-
this.changeDetectorRef.detectChanges();
346+
this.#changeDetectorRef.markForCheck();
347+
this.#changeDetectorRef.detectChanges();
352348
});
353349
});
354350
}
@@ -358,17 +354,17 @@ export class DropdownComponent implements AfterContentInit, OnDestroy, OnInit {
358354
this.clearListeners();
359355
this.popperInstance?.destroy();
360356
this.popperInstance=undefined;
361-
this.changeDetectorRef.markForCheck();
357+
this.#changeDetectorRef.markForCheck();
362358
}
363359

364360
privatesetListeners():void{
365361
this.listeners.push(
366-
this.renderer.listen(this.document,'click',(event)=>{
362+
this.#renderer.listen(this.#document,'click',(event)=>{
367363
consttarget=event.targetasHTMLElement;
368-
if(this._menuElementRef?.nativeElement.contains(event.target)){
364+
if(this._menuElementRef()?.nativeElement.contains(event.target)){
369365
this.clickedTarget=target;
370366
}
371-
if(this._toggler?.elementRef.nativeElement.contains(event.target)){
367+
if(this._toggler()?.elementRef.nativeElement.contains(event.target)){
372368
return;
373369
}
374370
constautoClose=this.autoClose();
@@ -387,7 +383,7 @@ export class DropdownComponent implements AfterContentInit, OnDestroy, OnInit {
387383
})
388384
);
389385
this.listeners.push(
390-
this.renderer.listen(this.elementRef.nativeElement,'keyup',(event)=>{
386+
this.#renderer.listen(this.#elementRef.nativeElement,'keyup',(event)=>{
391387
if(event.key==='Escape'&&this.autoClose()!==false){
392388
event.stopPropagation();
393389
this.setVisibleState(false);
@@ -396,11 +392,11 @@ export class DropdownComponent implements AfterContentInit, OnDestroy, OnInit {
396392
})
397393
);
398394
this.listeners.push(
399-
this.renderer.listen(this.document,'keyup',(event)=>{
395+
this.#renderer.listen(this.#document,'keyup',(event)=>{
400396
if(
401397
event.key==='Tab'&&
402398
this.autoClose()!==false&&
403-
!this.elementRef.nativeElement.contains(event.target)
399+
!this.#elementRef.nativeElement.contains(event.target)
404400
){
405401
this.setVisibleState(false);
406402
return;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp