src/lib/method-template.directive.ts
OnInit
OnChanges
| Selector | [rxapMethod] |
| Standalone | true |
| exportAs | rxapMethod |
Methods |
|
Inputs |
Outputs |
HostListeners |
constructor(template: TemplateRef<MethodTemplateDirectiveContext<ReturnType>>, viewContainerRef: ViewContainerRef, cdr: ChangeDetectorRef)
|
||||||||||||
|
Defined in src/lib/method-template.directive.ts:59
|
||||||||||||
|
Parameters :
|
| immediately | |
Type : boolean
|
|
Default value : false
|
|
|
Defined in src/lib/method-template.directive.ts:46
|
|
| rxapMethodCall | |
Type : Method<ReturnType | Parameters>
|
|
|
Defined in src/lib/method-template.directive.ts:36
|
|
| rxapMethodError | |
Type : TemplateRef<MethodTemplateDirectiveErrorContext>
|
|
|
Defined in src/lib/method-template.directive.ts:40
|
|
| rxapMethodLoading | |
Type : TemplateRef<void>
|
|
|
Defined in src/lib/method-template.directive.ts:42
|
|
| rxapMethodParameters | |
Type : Parameters
|
|
|
Defined in src/lib/method-template.directive.ts:38
|
|
| rxapMethodWithoutParameters | |
Type : boolean
|
|
Default value : false
|
|
|
Defined in src/lib/method-template.directive.ts:44
|
|
| embedded | |
Type : EventEmitter
|
|
|
Defined in src/lib/method-template.directive.ts:59
|
|
| executed | |
Type : EventEmitter
|
|
|
Defined in src/lib/method-template.directive.ts:48
|
|
| executing | |
Type : ToggleSubject
|
|
|
Defined in src/lib/method-template.directive.ts:57
|
|
|
true - a remote method call is in progress |
|
| failure | |
Type : EventEmitter
|
|
|
Defined in src/lib/method-template.directive.ts:50
|
|
| successful | |
Type : EventEmitter
|
|
|
Defined in src/lib/method-template.directive.ts:52
|
|
| confirmed |
|
Defined in src/lib/method-template.directive.ts:91
|
| Public Async execute | ||||||||
execute(parameters: Parameters | undefined)
|
||||||||
|
Defined in src/lib/method-template.directive.ts:95
|
||||||||
|
Parameters :
Returns :
Promise<void>
|
| Protected executed | ||||||
executed(result: any)
|
||||||
|
Defined in src/lib/method-template.directive.ts:121
|
||||||
|
Parameters :
Returns :
void
|
| Protected failure | ||||||
failure(error: Error)
|
||||||
|
Defined in src/lib/method-template.directive.ts:125
|
||||||
|
Parameters :
Returns :
void
|
| Static ngTemplateContextGuard | |||||||||
ngTemplateContextGuard(dir: MethodTemplateDirective<T>, ctx: any)
|
|||||||||
|
Defined in src/lib/method-template.directive.ts:71
|
|||||||||
Type parameters :
|
|||||||||
|
Parameters :
Returns :
MethodTemplateDirectiveContext<T>
|
| Public onConfirmed |
onConfirmed()
|
Decorators :
@HostListener('confirmed')
|
|
Defined in src/lib/method-template.directive.ts:91
|
|
Returns :
Promise<void>
|
| Protected renderErrorTemplate | ||||||
renderErrorTemplate(error: Error)
|
||||||
|
Defined in src/lib/method-template.directive.ts:133
|
||||||
|
Parameters :
Returns :
void
|
| Protected renderTemplate | ||||||
renderTemplate(result: ReturnType)
|
||||||
|
Defined in src/lib/method-template.directive.ts:147
|
||||||
|
Parameters :
Returns :
void
|
| Public setParameter | |||||||||
setParameter(parameterKey: Key, value)
|
|||||||||
|
Defined in src/lib/method-template.directive.ts:113
|
|||||||||
Type parameters :
|
|||||||||
|
Parameters :
Returns :
void
|
| Protected successful | ||||||
successful(result: ReturnType)
|
||||||
|
Defined in src/lib/method-template.directive.ts:129
|
||||||
|
Parameters :
Returns :
void
|
| Public updateParameters | ||||||
updateParameters(parameters: Partial
|
||||||
|
Defined in src/lib/method-template.directive.ts:117
|
||||||
|
Parameters :
Returns :
void
|
import {
ChangeDetectorRef,
Directive,
EventEmitter,
HostListener,
Inject,
Input,
isDevMode,
OnChanges,
OnInit,
Output,
SimpleChanges,
TemplateRef,
ViewContainerRef,
} from '@angular/core';
import { ToggleSubject } from '@rxap/rxjs';
import { Method } from '@rxap/pattern';
export interface MethodTemplateDirectiveContext<ReturnType = any> {
$implicit: ReturnType;
}
export interface MethodTemplateDirectiveErrorContext {
$implicit: Error;
message: string;
}
@Directive({
selector: '[rxapMethod]',
exportAs: 'rxapMethod',
standalone: true,
})
export class MethodTemplateDirective<ReturnType = any, Parameters = any> implements OnInit, OnChanges {
@Input('rxapMethodCall')
public method!: Method<ReturnType, Parameters>;
@Input('rxapMethodParameters')
public parameters?: Parameters;
@Input('rxapMethodError')
public errorTemplate?: TemplateRef<MethodTemplateDirectiveErrorContext>;
@Input('rxapMethodLoading')
public loadingTemplate?: TemplateRef<void>;
@Input('rxapMethodWithoutParameters')
public withoutParameters = false;
@Input()
public immediately = false;
@Output('executed')
public executed$ = new EventEmitter();
@Output('failure')
public failure$ = new EventEmitter<Error>();
@Output('successful')
public successful$ = new EventEmitter<ReturnType>();
/**
* true - a remote method call is in progress
*/
@Output('executing')
public executing$ = new ToggleSubject();
@Output()
public embedded = new EventEmitter();
constructor(
@Inject(TemplateRef)
private readonly template: TemplateRef<MethodTemplateDirectiveContext<ReturnType>>,
@Inject(ViewContainerRef)
private readonly viewContainerRef: ViewContainerRef,
@Inject(ChangeDetectorRef)
protected readonly cdr: ChangeDetectorRef,
) {
}
static ngTemplateContextGuard<T>(dir: MethodTemplateDirective<T>, ctx: any):
ctx is MethodTemplateDirectiveContext<T> {
return true;
}
public ngOnChanges(changes: SimpleChanges) {
const parametersChanges = changes['parameters'];
if (parametersChanges) {
this.execute(parametersChanges.currentValue);
}
}
public ngOnInit() {
this.renderLoadingTemplate();
if (this.withoutParameters) {
this.execute();
}
}
@HostListener('confirmed')
public onConfirmed() {
return this.execute();
}
public async execute(parameters: Parameters | undefined = this.parameters): Promise<void> {
this.executing$.enable();
try {
const result = await this.method.call(parameters);
this.executed(result);
this.renderTemplate(result);
this.successful(result);
} catch (error: any) {
if (isDevMode()) {
console.error(`Method directive execution failed:`, error.message);
}
this.renderErrorTemplate(error);
this.failure(error);
} finally {
this.executing$.disable();
}
}
public setParameter<Key extends keyof Parameters>(parameterKey: Key, value: Parameters[Key]): void {
this.updateParameters({ [parameterKey]: value } as any);
}
public updateParameters(parameters: Partial<Parameters>): void {
this.parameters = { ...(this.parameters ?? {}), ...parameters } as any;
}
protected executed(result: any) {
this.executed$.emit(result);
}
protected failure(error: Error) {
this.failure$.emit(error);
}
protected successful(result: ReturnType) {
this.successful$.emit(result);
}
protected renderErrorTemplate(error: Error) {
if (this.errorTemplate) {
this.viewContainerRef.clear();
if (this.errorTemplate) {
this.viewContainerRef.createEmbeddedView(this.errorTemplate,
{
$implicit: error,
message: error.message,
},
);
}
}
}
protected renderTemplate(result: ReturnType) {
this.viewContainerRef.clear();
try {
this.viewContainerRef.createEmbeddedView(this.template, { $implicit: result });
} catch (error: any) {
this.renderErrorTemplate(error);
console.error(error.message);
throw error;
}
this.embedded.emit();
this.cdr.detectChanges();
}
private renderLoadingTemplate() {
if (this.loadingTemplate) {
this.viewContainerRef.clear();
this.viewContainerRef.createEmbeddedView(this.loadingTemplate);
}
}
}