typescript - Vytvorte znovu použiteľnú modálnu komponentu v Angular
Podľa tohto tutoriálu som vytvoril opakovane použiteľnú a prispôsobiteľnú modálnu komponentu. Avšak mám jeden problém. Predstavte si, že sú dve komponenty, A a B, a v oboch otvorím modál pomocou modálnej komponenty. Pre komponentu A, keď používateľ klikne na tlačidlo odoslať, musí sa vykonať functionA() komponentu A, a pre B functionB() komponentu B. Ako môžem umožniť súboru modal.ts prístup k obom funkciám a ich vykonanie?
Ak je to možné, nechcem mať globálny súbor služieb, kde sú všetky funkcie, ani presúvať všetky súvisiace funkcie do súboru modal.ts, radšej si chcem udržať každý jednotlivý komponent čistý a oddelený, ale optimalizovať interakciu medzi nimi tak, aby som len odovzdával názov funkcie a požadované vstupné argumenty. Vie niekto, aká je najlepšia prax na dosiahnutie tohto? Vopred ďakujem.
.ts modálu:
open(): Promise<boolean> {
...
}
async close(): Promise<void> {
const result = await this.modalConfig.onClose();
this.modalRef.close(result);
}
async dismiss(): Promise<void> {
...
}
}
config.ts modalu:
export class ModalConfig {
modalTitle: string;
data: string = '';
onClose?(): Promise<boolean> | boolean;
}
.html modálneho okna:
<ng-template #modal>
<div class="modal-header">
<button type="button" (click)="dismiss()">cancel</button>
<button type="button" (click)="close()">Ok</button>
</div>
</ng-template>
Odpoveď č. 1
Vytvoril som túto jednoduchú fungujúcu verziu, aby ste pochopili modulárnu komponentu modálneho okna, prosím, prejdite si kód a dajte mi vedieť, ak by boli nejaké problémy, môžeme modálne okno napísať raz a ľahko ho používať v celom aplikácii!
modálna komponenta
html
<div
class="modal"
tabindex="-1"
role="dialog"
*ngIf="open"
style="display:block;"
>
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">{{ config.title }}</h5>
<button
type="button"
class="close"
data-dismiss="modal"
aria-label="Close"
(click)="discardWrapper($event)"
>
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>{{ config.description }}</p>
</div>
<div class="modal-footer">
<button
type="button"
class="btn btn-primary"
(click)="saveWrapper($event)"
>
Save changes
</button>
<button
type="button"
class="btn btn-secondary"
data-dismiss="modal"
(click)="discardWrapper($event)"
>
Close
</button>
</div>
</div>
</div>
</div>
ts
import { CommonModule } from '@angular/common';
import { Component, OnInit } from '@angular/core';
import { ModalService } from './modal.service';
export class ModalConfig {
title?: string = '';
description?: string = '';
save?: Function = () => {};
discard?: Function = () => {};
constructor(
title: string = '',
description: string = '',
save = null,
discard = null
) {
if (title) this.title = title;
if (description) this.description = description;
if (save) this.save = save;
if (discard) this.discard = discard;
}
}
@Component({
selector: 'app-modal',
templateUrl: './modal.component.html',
styleUrls: ['./modal.component.css'],
imports: [CommonModule],
standalone: true,
})
export class ModalComponent implements OnInit {
constructor(private modalService: ModalService) {}
get open() {
return this.modalService.isOpen;
}
get config() {
return this.modalService.config;
}
discardWrapper(event: Event) {
this.modalService.isOpen = false;
if (this.config.discard) {
this.config.discard(event);
}
}
saveWrapper(event: Event) {
this.modalService.isOpen = false;
if (this.config.save) {
this.config.save(event);
}
}
ngOnInit() {}
}
služba
import { Injectable } from '@angular/core';
import { ModalConfig } from './modal.component';
@Injectable({
providedIn: 'root',
})
export class ModalService {
isOpen = false;
config = new ModalConfig();
constructor() {}
open(config: ModalConfig) {
this.config = { ...this.config, ...config };
this.isOpen = true;
}
}
Komponent používajúci túto logiku
ts
import { Component, OnInit } from '@angular/core';
import { ModalService } from '../modal/modal.service';
@Component({
selector: 'app-a',
templateUrl: './a.component.html',
styleUrls: ['./a.component.css'],
standalone: true,
})
export class AComponent implements OnInit {
constructor(private modalService: ModalService) {}
ngOnInit() {}
openModal() {
this.modalService.open({
title: 'test',
description: 'test description',
});
}
}
html
<p>a works!</p>
<button (click)="openModal()" class="btn btn-primary">open modal</button>
stackblitz
Odpoveď č. 2
Presuňte metódy dismiss() a close() do služby a volajte ich odtiaľ. Toto by malo vyriešiť váš problém.
