-
-
Save lehuynhdong1/c202119185adc20751597df5a5828b64 to your computer and use it in GitHub Desktop.
Directive BaseComponent for convenient use of the Angular lifecycle hook
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { AfterViewInit, Directive, HostBinding, OnDestroy, OnInit, inject } from '@angular/core'; | |
import { Subscribable } from './subscribable'; | |
import { ThemeService } from '../../services/theme.service'; | |
import { Theme } from '../../enums/theme.enum'; | |
import { TranslocoService } from '@ngneat/transloco'; | |
@Directive() | |
export abstract class BaseComponent extends Subscribable implements OnInit, AfterViewInit, OnDestroy { | |
@HostBinding('style.display') display = 'block'; | |
public ngOnInit(): void { | |
this.onInit(); | |
} | |
public ngAfterViewInit(): void { | |
this.onAfterViewInit(); | |
} | |
public override ngOnDestroy(): void { | |
super.ngOnDestroy(); | |
this.onDestroy(); | |
} | |
protected onInit(): void { | |
// virtual method | |
} | |
protected onAfterViewInit(): void { | |
// virtual method | |
} | |
protected onDestroy(): void { | |
// virtual method | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; | |
import { CommonModule } from '@angular/common'; | |
import { BaseComponent } from '../core/components/base-component/base.component'; | |
import { filter, of, takeUntil } from 'rxjs'; | |
import { NavigationEnd, Router } from '@angular/router'; | |
@Component({ | |
selector: 'app-same-use-case', | |
standalone: true, | |
imports: [CommonModule], | |
template: `<p>same-use-case works!</p>`, | |
styles: [], | |
changeDetection: ChangeDetectionStrategy.OnPush, | |
}) | |
export class SameUseCaseComponent extends BaseComponent { | |
private readonly router = inject(Router); | |
protected override onInit(): void { | |
// ngOnInit | |
// ... | |
// subscribe | |
this.subscribe(of(true), res => { | |
console.log(res); | |
}); | |
// subscribeOne | |
this.subscribeOne(of(true), res => { | |
console.log(res); | |
}); | |
// addSubscription | |
const subscription$ = of(true).subscribe({ | |
next: res => { | |
console.log(res); | |
}, | |
error: err => { | |
console.log(err); | |
}, | |
}); | |
this.addSubscription(subscription$); | |
// onDestroySubject | |
this.router.events | |
.pipe( | |
filter(event => event instanceof NavigationEnd), | |
takeUntil(this.onDestroySubject) | |
) | |
.subscribe(event => { | |
console.log(event); | |
}); | |
} | |
protected override onAfterViewInit(): void { | |
// ngAfterViewInit | |
} | |
protected override onDestroy(): void { | |
// ngDestroy | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Directive, OnDestroy } from '@angular/core'; | |
import { Observable, Subject, Subscription } from 'rxjs'; | |
import { SubscriptionCollection } from './subscription-collection'; | |
import { take } from 'rxjs/operators'; | |
@Directive() | |
export abstract class Subscribable implements OnDestroy { | |
protected onDestroySubject: Subject<void> = new Subject(); | |
protected subscriptionCollection = new SubscriptionCollection(); | |
public ngOnDestroy(): void { | |
// Subject | |
// using for takeUntil | |
this.onDestroySubject.next(); | |
this.onDestroySubject.complete(); | |
// Subscription | |
this.subscriptionCollection.clear(); | |
this.onUnsubscribe(); | |
} | |
protected subscribe<T>(observable: Observable<T>, handler: (data: T) => void): void { | |
this.subscriptionCollection.add(observable, handler); | |
} | |
protected subscribeOne<T>(observable: Observable<T>, handler: (data: T) => void): void { | |
observable.pipe(take(1)).subscribe(data => handler(data)); | |
} | |
protected addSubscription(...subscriptions: Array<Subscription>): void { | |
this.subscriptionCollection.addItems(subscriptions); | |
// Add finalize callback here to remove subscription from the subscription collection | |
// at the moment subscription has changed its status to COMPLETED | |
subscriptions.forEach(sub => { | |
const subscriptionRef = sub; | |
sub.add(() => { | |
this.subscriptionCollection.removeItem(subscriptionRef); | |
}); | |
}); | |
} | |
protected onUnsubscribe(): void { | |
// virtual method | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Observable, Subscription } from 'rxjs'; | |
export class SubscriptionCollection { | |
private subscriptionRefs: Subscription[] = []; | |
public clear(): void { | |
this.subscriptionRefs.forEach(s => !s.closed && s.unsubscribe()); | |
} | |
public add<T>(observable: Observable<T>, handler: (data: T) => void): void { | |
const subscription: Subscription = observable.subscribe(data => { | |
handler(data); | |
}); | |
this.subscriptionRefs.push(subscription); | |
} | |
public addItems(subscriptions: Subscription[]): void { | |
this.subscriptionRefs.push(...subscriptions); | |
} | |
public removeItem(subscriptions: Subscription): void { | |
const index = this.subscriptionRefs.findIndex(s => s === subscriptions); | |
if (index >= 0) { | |
this.subscriptionRefs.splice(index, 1); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment