From a366c1846ad48bf7c89b3cad01a0ccecfa764cd3 Mon Sep 17 00:00:00 2001 From: Florent Poittevin <florent.poittevin@unige.ch> Date: Thu, 4 Jul 2019 16:01:19 +0200 Subject: [PATCH] Add subscription system --- .../core-abstract/core-abstract.component.ts | 5 + .../core-abstract/core-abstract.directive.ts | 5 + .../core-abstract-angular-element.model.ts | 209 ++++++++++++++++++ .../managers/subscription-manager.model.ts | 58 +++++ .../observables/counter-subject.model.ts | 34 +++ .../pipes/core-abstract/core-abstract.pipe.ts | 5 + .../tools => core/tools/is}/is.tool.ts | 0 src/app/core/utils/subscription.util.ts | 18 ++ .../components/abstract/abstract.component.ts | 5 + .../directives/abstract/abstract.directive.ts | 5 + src/app/shared/directives/base.directive.ts | 2 +- .../shared/pipes/abstract/abstract.pipe.ts | 5 + .../shared/pipes/is-pipes/is-boolean.pipe.ts | 2 +- .../shared/pipes/is-pipes/is-false.pipe.ts | 2 +- .../shared/pipes/is-pipes/is-function.pipe.ts | 2 +- .../pipes/is-pipes/is-number-finite.pipe.ts | 2 +- .../pipes/is-pipes/is-number-invalid.pipe.ts | 2 +- .../pipes/is-pipes/is-number-valid.pipe.ts | 2 +- .../shared/pipes/is-pipes/is-number.pipe.ts | 2 +- src/app/shared/pipes/is-pipes/is-true.pipe.ts | 2 +- .../pipes/is-pipes/is-truthy-object.pipe.ts | 2 +- .../shared/pipes/is-pipes/is-truthy.pipe.ts | 2 +- .../shared/utils/solidify-metadata.util.ts | 4 +- .../abstract-detail/abstract-detail.view.ts | 15 +- 24 files changed, 371 insertions(+), 19 deletions(-) create mode 100644 src/app/core/components/core-abstract/core-abstract.component.ts create mode 100644 src/app/core/directives/core-abstract/core-abstract.directive.ts create mode 100644 src/app/core/models/angular/core-abstract-angular-element.model.ts create mode 100644 src/app/core/models/managers/subscription-manager.model.ts create mode 100644 src/app/core/models/observables/counter-subject.model.ts create mode 100644 src/app/core/pipes/core-abstract/core-abstract.pipe.ts rename src/app/{shared/tools => core/tools/is}/is.tool.ts (100%) create mode 100644 src/app/core/utils/subscription.util.ts create mode 100644 src/app/shared/components/abstract/abstract.component.ts create mode 100644 src/app/shared/directives/abstract/abstract.directive.ts create mode 100644 src/app/shared/pipes/abstract/abstract.pipe.ts diff --git a/src/app/core/components/core-abstract/core-abstract.component.ts b/src/app/core/components/core-abstract/core-abstract.component.ts new file mode 100644 index 000000000..1ff3c1c59 --- /dev/null +++ b/src/app/core/components/core-abstract/core-abstract.component.ts @@ -0,0 +1,5 @@ +import {CoreAbstractAngularElement} from "@app/core/models/angular/core-abstract-angular-element.model"; + +export class CoreAbstractComponent extends CoreAbstractAngularElement { + +} diff --git a/src/app/core/directives/core-abstract/core-abstract.directive.ts b/src/app/core/directives/core-abstract/core-abstract.directive.ts new file mode 100644 index 000000000..8e5c97c7b --- /dev/null +++ b/src/app/core/directives/core-abstract/core-abstract.directive.ts @@ -0,0 +1,5 @@ +import {CoreAbstractAngularElement} from "@app/core/models/angular/core-abstract-angular-element.model"; + +export class CoreAbstractDirective extends CoreAbstractAngularElement { + +} diff --git a/src/app/core/models/angular/core-abstract-angular-element.model.ts b/src/app/core/models/angular/core-abstract-angular-element.model.ts new file mode 100644 index 000000000..09f466db4 --- /dev/null +++ b/src/app/core/models/angular/core-abstract-angular-element.model.ts @@ -0,0 +1,209 @@ +import { + AfterContentChecked, + AfterContentInit, + AfterViewChecked, + AfterViewInit, + ChangeDetectorRef, + DoCheck, + EventEmitter, + OnChanges, + OnDestroy, + OnInit, + SimpleChanges, +} from "@angular/core"; +import {SubscriptionManager} from "@app/core/models/managers/subscription-manager.model"; +import {CounterSubject} from "@app/core/models/observables/counter-subject.model"; +import {isFunction, isTruthyObject} from "@app/core/tools/is/is.tool"; +import {Observable, Subscription} from "rxjs"; + +export class CoreAbstractAngularElement implements OnChanges, OnInit, DoCheck, AfterContentInit, AfterContentChecked, AfterViewInit, AfterViewChecked, OnDestroy { + + /* Subscription manager */ + + protected readonly _subscriptionManager: SubscriptionManager = new SubscriptionManager(); + + /* Angular state */ + + get changed(): boolean { + return this._ngOnChangesCS.hasCount(); + } + + get changesCount(): number { + return this._ngOnChangesCS.getValue(); + } + + private _initialized: boolean = false; + + get initialized(): boolean { + return this._initialized; + } + + get checked(): boolean { + return this._ngDoCheckCS.hasCount(); + } + + get checksCount(): number { + return this._ngDoCheckCS.getValue(); + } + + private _contentInitialized: boolean = false; + + get contentInitialized(): boolean { + return this._contentInitialized; + } + + get contentChecked(): boolean { + return this._ngAfterContentCheckedCS.hasCount(); + } + + get contentChecksCount(): number { + return this._ngAfterContentCheckedCS.getValue(); + } + + private _viewInitialized: boolean = false; + + get viewInitialized(): boolean { + return this._viewInitialized; + } + + get viewChecked(): boolean { + return this._ngAfterViewCheckedCS.hasCount(); + } + + get viewChecksCount(): number { + return this._ngAfterViewCheckedCS.getValue(); + } + + private _destroyed: boolean = false; + + get destroyed(): boolean { + return this._destroyed; + } + + /* Angular frequent lifecycle hooks counter subjects */ + + private readonly _ngOnChangesCS: CounterSubject = new CounterSubject(); + + private readonly _ngDoCheckCS: CounterSubject = new CounterSubject(); + + private readonly _ngAfterContentCheckedCS: CounterSubject = new CounterSubject(); + + private readonly _ngAfterViewCheckedCS: CounterSubject = new CounterSubject(); + + /* Angular occasional lifecycle hooks event emitters */ + + private readonly _ngOnInitEventEmitter: EventEmitter<boolean> = new EventEmitter<boolean>(); + + private readonly _ngAfterContentInitEventEmitter: EventEmitter<boolean> = new EventEmitter<boolean>(); + + private readonly _ngAfterViewInitEventEmitter: EventEmitter<boolean> = new EventEmitter<boolean>(); + + private readonly _ngOnDestroyEventEmitter: EventEmitter<boolean> = new EventEmitter<boolean>(); + + /* Angular lifecycle hooks value event emitters */ + + private readonly _ngOnChangesValueEventEmitter: EventEmitter<SimpleChanges> = new EventEmitter<SimpleChanges>(); + + /* Angular lifecycle hooks base implementation */ + + ngOnChanges(changes: SimpleChanges): void { + // Fix ngOnInit + if (this.changed && !this.initialized) { + this.ngOnInit(); + } + this._ngOnChangesValueEventEmitter.emit(changes); + this._ngOnChangesCS.increment(); + } + + ngOnInit(): void { + if (!this._initialized) { + this._initialized = true; + this._ngOnInitEventEmitter.emit(true); + } else { + this._ngOnInitEventEmitter.emit(false); + } + } + + ngDoCheck(): void { + this._ngDoCheckCS.increment(); + } + + ngAfterContentInit(): void { + if (!this._contentInitialized) { + this._contentInitialized = true; + this._ngAfterContentInitEventEmitter.emit(true); + } else { + this._ngAfterContentInitEventEmitter.emit(false); + } + } + + ngAfterContentChecked(): void { + this._ngAfterContentCheckedCS.increment(); + } + + ngAfterViewInit(): void { + if (!this._viewInitialized) { + this._viewInitialized = true; + this._ngAfterViewInitEventEmitter.emit(true); + } else { + this._ngAfterViewInitEventEmitter.emit(false); + } + } + + ngAfterViewChecked(): void { + this._ngAfterViewCheckedCS.increment(); + } + + ngOnDestroy(): void { + if (!this._destroyed) { + this._destroyed = true; + this._ngOnDestroyEventEmitter.emit(true); + } else { + this._ngOnDestroyEventEmitter.emit(false); + } + this._subscriptionManager.clearAndUnsubscribeAll(); + } + + /* Angular lifecycle hooks observables */ + + readonly ngOnChangesObs: Observable<number> = this._ngOnChangesCS.asObservable(); + + readonly ngOnChangesValueObs: Observable<SimpleChanges> = this._ngOnChangesValueEventEmitter.asObservable(); + + readonly ngOnInitObs: Observable<boolean> = this._ngOnInitEventEmitter.asObservable(); + + readonly ngDoCheckObs: Observable<number> = this._ngDoCheckCS.asObservable(); + + readonly ngAfterContentInitObs: Observable<boolean> = this._ngAfterContentInitEventEmitter.asObservable(); + + readonly ngAfterContentCheckedObs: Observable<number> = this._ngAfterContentCheckedCS.asObservable(); + + readonly ngAfterViewInitObs: Observable<boolean> = this._ngAfterViewInitEventEmitter.asObservable(); + + readonly ngAfterViewCheckedObs: Observable<number> = this._ngAfterViewCheckedCS.asObservable(); + + readonly ngOnDestroyObs: Observable<boolean> = this._ngOnDestroyEventEmitter.asObservable(); + + /* Detect changes */ + + detectChanges(changeDetectorRef: ChangeDetectorRef): boolean { + if (this.initialized + && !this.destroyed + && isTruthyObject(changeDetectorRef) + && isFunction(changeDetectorRef.detectChanges)) { + changeDetectorRef.detectChanges(); + return true; + } + return false; + } + + /* Subscribe */ + + subscribe<T>(observable: Observable<T>, + onNext?: (value: T) => void, + onError?: (error: Error) => void, + onComplete?: () => void): Subscription { + return this._subscriptionManager.subscribe(observable, onNext, onError, onComplete); + } + +} diff --git a/src/app/core/models/managers/subscription-manager.model.ts b/src/app/core/models/managers/subscription-manager.model.ts new file mode 100644 index 000000000..714d9ff50 --- /dev/null +++ b/src/app/core/models/managers/subscription-manager.model.ts @@ -0,0 +1,58 @@ +import {SubscriptionUtil} from "@app/core/utils/subscription.util"; +import {Observable, Subscription} from "rxjs"; + +export class SubscriptionManager { + + private readonly _subscriptions: Subscription[] = []; + + geSubscriptions(): Subscription[] { + return this._subscriptions.slice(); + } + + subscribe<T>(observable: Observable<T>, + onNext?: (value: T) => void, + onError?: (error: Error) => void, + onComplete?: () => void): Subscription { + const subscription = observable.subscribe(onNext, onError, onComplete); + this.add(subscription); + return subscription; + } + + add(subscription: Subscription): boolean { + if (SubscriptionUtil.isUnsubscribable(subscription)) { + this._subscriptions.push(subscription); + return true; + } + return false; + } + + addMultiple(...subscriptions: Subscription[]): number { + return subscriptions.reduce((seed, next) => seed + (this.add(next) ? 1 : 0), 0); + } + + remove(subscription: Subscription): boolean { + const index = this._subscriptions.indexOf(subscription); + if (index < 0) { + return false; + } + this._subscriptions.splice(index, 1); + return true; + } + + clear(): boolean { + if (this._subscriptions.length === 0) { + return false; + } + this._subscriptions.splice(0); + return true; + } + + removeAndUnsubscribe(subscription: Subscription): boolean { + return this.remove(subscription) && SubscriptionUtil.unsubscribe(subscription); + } + + clearAndUnsubscribeAll(): number { + return this._subscriptions.splice(0).reduce((seed, next) => seed + (SubscriptionUtil.unsubscribe(next) ? 1 : 0), 0); + } + +} diff --git a/src/app/core/models/observables/counter-subject.model.ts b/src/app/core/models/observables/counter-subject.model.ts new file mode 100644 index 000000000..3090817fa --- /dev/null +++ b/src/app/core/models/observables/counter-subject.model.ts @@ -0,0 +1,34 @@ +import {isNumberReal} from "@app/core/tools/is/is.tool"; +import {BehaviorSubject} from "rxjs"; + +export class CounterSubject extends BehaviorSubject<number> { + + private static _toSafeValue(value: any): number { + return isNumberReal(value) && value >= 0 ? value : 0; + } + + constructor(initialCount: number = 0) { + super(CounterSubject._toSafeValue(initialCount)); + } + + next(count: any): void { + super.next(CounterSubject._toSafeValue(parseFloat(count))); + } + + hasCount(): boolean { + return this.getValue() > 0; + } + + increment(increment: number = 1): number { + const result = this.getValue() + parseFloat(increment as any); + this.next(result); + return result; + } + + decrement(decrement: number = 1): number { + const result = this.getValue() - parseFloat(decrement as any); + this.next(result); + return result; + } + +} diff --git a/src/app/core/pipes/core-abstract/core-abstract.pipe.ts b/src/app/core/pipes/core-abstract/core-abstract.pipe.ts new file mode 100644 index 000000000..276b756a5 --- /dev/null +++ b/src/app/core/pipes/core-abstract/core-abstract.pipe.ts @@ -0,0 +1,5 @@ +import {CoreAbstractAngularElement} from "@app/core/models/angular/core-abstract-angular-element.model"; + +export class CoreAbstractPipe extends CoreAbstractAngularElement { + +} diff --git a/src/app/shared/tools/is.tool.ts b/src/app/core/tools/is/is.tool.ts similarity index 100% rename from src/app/shared/tools/is.tool.ts rename to src/app/core/tools/is/is.tool.ts diff --git a/src/app/core/utils/subscription.util.ts b/src/app/core/utils/subscription.util.ts new file mode 100644 index 000000000..eb17a7f66 --- /dev/null +++ b/src/app/core/utils/subscription.util.ts @@ -0,0 +1,18 @@ +import {isFunction, isReference, isTruthy} from "@app/core/tools/is/is.tool"; +import {Subscription} from "rxjs"; + +export class SubscriptionUtil { + + static isUnsubscribable(subscription: Subscription): boolean { + return isReference(subscription) && isFunction(subscription.unsubscribe) && !subscription.closed; + } + + static unsubscribe(subscription: Subscription): boolean { + if (this.isUnsubscribable(subscription)) { + subscription.unsubscribe(); + return isTruthy(subscription.closed); + } + return false; + } + +} diff --git a/src/app/shared/components/abstract/abstract.component.ts b/src/app/shared/components/abstract/abstract.component.ts new file mode 100644 index 000000000..fb932b30f --- /dev/null +++ b/src/app/shared/components/abstract/abstract.component.ts @@ -0,0 +1,5 @@ +import {CoreAbstractComponent} from "@app/core/components/core-abstract/core-abstract.component"; + +export class AbstractComponent extends CoreAbstractComponent { + +} diff --git a/src/app/shared/directives/abstract/abstract.directive.ts b/src/app/shared/directives/abstract/abstract.directive.ts new file mode 100644 index 000000000..63bb248a2 --- /dev/null +++ b/src/app/shared/directives/abstract/abstract.directive.ts @@ -0,0 +1,5 @@ +import {CoreAbstractDirective} from "@app/core/directives/core-abstract/core-abstract.directive"; + +export class AbstractDirective extends CoreAbstractDirective { + +} diff --git a/src/app/shared/directives/base.directive.ts b/src/app/shared/directives/base.directive.ts index bfe63878d..5a56a13b4 100644 --- a/src/app/shared/directives/base.directive.ts +++ b/src/app/shared/directives/base.directive.ts @@ -16,7 +16,7 @@ export abstract class BaseDirective implements OnDestroy { }); } - addToSubscription(subscription: Subscription) { + addToSubscription(subscription: Subscription): void { this.listSubscription.push(subscription); } } diff --git a/src/app/shared/pipes/abstract/abstract.pipe.ts b/src/app/shared/pipes/abstract/abstract.pipe.ts new file mode 100644 index 000000000..d5601775d --- /dev/null +++ b/src/app/shared/pipes/abstract/abstract.pipe.ts @@ -0,0 +1,5 @@ +import {CoreAbstractPipe} from "@app/core/pipes/core-abstract/core-abstract.pipe"; + +export class AbstractPipe extends CoreAbstractPipe { + +} diff --git a/src/app/shared/pipes/is-pipes/is-boolean.pipe.ts b/src/app/shared/pipes/is-pipes/is-boolean.pipe.ts index 474514e7b..f108e148c 100644 --- a/src/app/shared/pipes/is-pipes/is-boolean.pipe.ts +++ b/src/app/shared/pipes/is-pipes/is-boolean.pipe.ts @@ -1,6 +1,6 @@ import {Pipe, PipeTransform} from "@angular/core"; -import {isBoolean} from "@app/shared/tools/is.tool"; +import {isBoolean} from "@app/core/tools/is/is.tool"; @Pipe({ name: "isBoolean", diff --git a/src/app/shared/pipes/is-pipes/is-false.pipe.ts b/src/app/shared/pipes/is-pipes/is-false.pipe.ts index c80f8c776..54bf6c83c 100644 --- a/src/app/shared/pipes/is-pipes/is-false.pipe.ts +++ b/src/app/shared/pipes/is-pipes/is-false.pipe.ts @@ -1,6 +1,6 @@ import {Pipe, PipeTransform} from "@angular/core"; -import {isFalse} from "@app/shared/tools/is.tool"; +import {isFalse} from "@app/core/tools/is/is.tool"; @Pipe({ name: "isFalse", diff --git a/src/app/shared/pipes/is-pipes/is-function.pipe.ts b/src/app/shared/pipes/is-pipes/is-function.pipe.ts index fc27d7da8..d3acb362d 100644 --- a/src/app/shared/pipes/is-pipes/is-function.pipe.ts +++ b/src/app/shared/pipes/is-pipes/is-function.pipe.ts @@ -1,6 +1,6 @@ import {Pipe, PipeTransform} from "@angular/core"; -import {isBoolean, isFunction} from "@app/shared/tools/is.tool"; +import {isBoolean, isFunction} from "@app/core/tools/is/is.tool"; @Pipe({ name: "isFunction", diff --git a/src/app/shared/pipes/is-pipes/is-number-finite.pipe.ts b/src/app/shared/pipes/is-pipes/is-number-finite.pipe.ts index 544716e4e..a925b06e4 100644 --- a/src/app/shared/pipes/is-pipes/is-number-finite.pipe.ts +++ b/src/app/shared/pipes/is-pipes/is-number-finite.pipe.ts @@ -1,6 +1,6 @@ import {Pipe, PipeTransform} from "@angular/core"; -import {isBoolean, isNumberFinite} from "@app/shared/tools/is.tool"; +import {isBoolean, isNumberFinite} from "@app/core/tools/is/is.tool"; @Pipe({ name: "isNumberFinite", diff --git a/src/app/shared/pipes/is-pipes/is-number-invalid.pipe.ts b/src/app/shared/pipes/is-pipes/is-number-invalid.pipe.ts index 83f616dd3..812be1ef2 100644 --- a/src/app/shared/pipes/is-pipes/is-number-invalid.pipe.ts +++ b/src/app/shared/pipes/is-pipes/is-number-invalid.pipe.ts @@ -1,6 +1,6 @@ import {Pipe, PipeTransform} from "@angular/core"; -import {isBoolean, isNumberInvalid} from "@app/shared/tools/is.tool"; +import {isBoolean, isNumberInvalid} from "@app/core/tools/is/is.tool"; @Pipe({ name: "isNumberInvalid", diff --git a/src/app/shared/pipes/is-pipes/is-number-valid.pipe.ts b/src/app/shared/pipes/is-pipes/is-number-valid.pipe.ts index ceeb0308b..01332171e 100644 --- a/src/app/shared/pipes/is-pipes/is-number-valid.pipe.ts +++ b/src/app/shared/pipes/is-pipes/is-number-valid.pipe.ts @@ -1,6 +1,6 @@ import {Pipe, PipeTransform} from "@angular/core"; -import {isBoolean, isNumberValid} from "@app/shared/tools/is.tool"; +import {isBoolean, isNumberValid} from "@app/core/tools/is/is.tool"; @Pipe({ name: "isNumberValid", diff --git a/src/app/shared/pipes/is-pipes/is-number.pipe.ts b/src/app/shared/pipes/is-pipes/is-number.pipe.ts index b1c748cf0..8caaf3154 100644 --- a/src/app/shared/pipes/is-pipes/is-number.pipe.ts +++ b/src/app/shared/pipes/is-pipes/is-number.pipe.ts @@ -1,6 +1,6 @@ import {Pipe, PipeTransform} from "@angular/core"; -import {isBoolean, isNumber} from "@app/shared/tools/is.tool"; +import {isBoolean, isNumber} from "@app/core/tools/is/is.tool"; @Pipe({ name: "isNumber", diff --git a/src/app/shared/pipes/is-pipes/is-true.pipe.ts b/src/app/shared/pipes/is-pipes/is-true.pipe.ts index adcdf9cc4..fd80a1f6b 100644 --- a/src/app/shared/pipes/is-pipes/is-true.pipe.ts +++ b/src/app/shared/pipes/is-pipes/is-true.pipe.ts @@ -1,6 +1,6 @@ import {Pipe, PipeTransform} from "@angular/core"; -import {isBoolean, isTrue} from "@app/shared/tools/is.tool"; +import {isBoolean, isTrue} from "@app/core/tools/is/is.tool"; @Pipe({ name: "isTrue", diff --git a/src/app/shared/pipes/is-pipes/is-truthy-object.pipe.ts b/src/app/shared/pipes/is-pipes/is-truthy-object.pipe.ts index e4745edc1..0d8e97f31 100644 --- a/src/app/shared/pipes/is-pipes/is-truthy-object.pipe.ts +++ b/src/app/shared/pipes/is-pipes/is-truthy-object.pipe.ts @@ -1,6 +1,6 @@ import {Pipe, PipeTransform} from "@angular/core"; -import {isTruthyObject} from "@app/shared/tools/is.tool"; +import {isTruthyObject} from "@app/core/tools/is/is.tool"; @Pipe({ name: "isTruthyObject", diff --git a/src/app/shared/pipes/is-pipes/is-truthy.pipe.ts b/src/app/shared/pipes/is-pipes/is-truthy.pipe.ts index 9c0b3815f..430a37bd9 100644 --- a/src/app/shared/pipes/is-pipes/is-truthy.pipe.ts +++ b/src/app/shared/pipes/is-pipes/is-truthy.pipe.ts @@ -1,6 +1,6 @@ import {Pipe, PipeTransform} from "@angular/core"; -import {isBoolean, isTruthy} from "@app/shared/tools/is.tool"; +import {isBoolean, isTruthy} from "@app/core/tools/is/is.tool"; @Pipe({ name: "isTruthy", diff --git a/src/app/shared/utils/solidify-metadata.util.ts b/src/app/shared/utils/solidify-metadata.util.ts index 28757fb92..516791d14 100644 --- a/src/app/shared/utils/solidify-metadata.util.ts +++ b/src/app/shared/utils/solidify-metadata.util.ts @@ -1,5 +1,5 @@ +import {isTruthyObject} from "@app/core/tools/is/is.tool"; import {RegisteredCrudAction} from "@app/shared/decorators/crud.decorator"; -import {isUndefined} from "@app/shared/tools/is.tool"; export const SOLIDIFY_META_KEY = "SOLIDIFY_META"; @@ -19,7 +19,7 @@ export class SolidifyMetadataUtil { * Ensures metadata is attached to the class and returns it. */ static ensureStoreSolidifyMetadata(target: SolidifyStateClass): SolidifyMetaDataModel { - if (isUndefined(target[SOLIDIFY_META_KEY] === undefined)) { + if (!isTruthyObject(target[SOLIDIFY_META_KEY])) { target[SOLIDIFY_META_KEY] = {}; } return target[SOLIDIFY_META_KEY]; diff --git a/src/app/shared/views/abstract-detail/abstract-detail.view.ts b/src/app/shared/views/abstract-detail/abstract-detail.view.ts index 8f5573699..c10827180 100644 --- a/src/app/shared/views/abstract-detail/abstract-detail.view.ts +++ b/src/app/shared/views/abstract-detail/abstract-detail.view.ts @@ -2,10 +2,10 @@ import {ComponentType} from "@angular/cdk/portal"; import {OnInit} from "@angular/core"; import {MatDialog} from "@angular/material"; import {ActivatedRoute} from "@angular/router"; +import {AbstractComponent} from "@app/shared/components/abstract/abstract.component"; import {CrudNameSpace} from "@app/shared/crud.namespace"; import {CrudStateModel} from "@app/shared/crud.state"; import {AbstractDeleteDialog} from "@app/shared/dialogs/abstract-delete/abstract-delete.dialog"; -import {BaseDirective} from "@app/shared/directives/base.directive"; import {ModelAttributeEnum} from "@app/shared/enums/model-attribute.enum"; import {StateEnum} from "@app/shared/enums/state.enum"; import {DeleteDialogModel} from "@app/shared/models/delete-dialog.model"; @@ -17,7 +17,7 @@ import {Store} from "@ngxs/store"; import {Observable} from "rxjs"; import {take} from "rxjs/operators"; -export abstract class AbstractDetailView<T, U extends CrudStateModel<T>> extends BaseDirective implements OnInit { +export abstract class AbstractDetailView<T, U extends CrudStateModel<T>> extends AbstractComponent implements OnInit { isLoading$: Observable<boolean>; current$: Observable<T>; @@ -39,6 +39,7 @@ export abstract class AbstractDetailView<T, U extends CrudStateModel<T>> extends } ngOnInit(): void { + super.ngOnInit(); this.store.dispatch(CrudActionUtil.loadResource(this.crudActionNameSpace)); this.retreiveCurrentModelWithUrl(); } @@ -65,10 +66,12 @@ export abstract class AbstractDetailView<T, U extends CrudStateModel<T>> extends delete() { const datas = {} as DeleteDialogModel; - this.addToSubscription(this.current$.pipe(take(1)).subscribe((model: T) => { - datas.name = model[this.KEY_PARAM_NAME]; - datas.resId = model[ModelAttributeEnum.resId]; - })); + this.subscribe( + this.current$.pipe(take(1)), + (model: T) => { + datas.name = model[this.KEY_PARAM_NAME]; + datas.resId = model[ModelAttributeEnum.resId]; + }); const dialogRef = this.dialog.open(CrudDialogUtil.delete(this.state) as ComponentType<AbstractDeleteDialog<T, U>>, { width: "250px", data: datas, -- GitLab