angular - Kako otvoriti komponentu iz modula koji se učitava na zahtjev u NgbModal?
Suočavam se s problemom prilikom pokušaja učitavanja dinamičke komponente iz modul učitanog na zahtjev. Preciznije, pokušavam otvoriti komponentu za prijavu u modalnom prozoru (https://ng-bootstrap.github.io/#/components/modal/examples) umjesto na zasebnoj stranici, dok istovremeno želim zadržati zasebnu rutu/stranicu za prijavu netaknutom.
Sada, jedna opcija mi se čini da moram eager učitati login komponentu u app modulu, što nije ništa drugo nego privremeni trik. Dakle, ne želim ovo rješenje.
Pokušao sam izravno koristiti komponentu, ali kao što sam i očekivao, pojavila mi se sljedeća pogreška:
Nije pronađena tvornička komponenta za SigninComponent. Jeste li je dodali u @NgModule.entryComponents?
Pretražio sam i pronašao ovaj link: https://github.com/angular/angular/issues/14324, ali ne mogu ga natjerati da radi.
Iznenađen sam što nisam mogao pronaći odgovarajuće rješenje za ovaj problem jer se radi o vrlo čestom slučaju. Bilo kakva pomoć ili prijedlozi su cijenjeni. Hvala!
Odgovor #1
Komponente koje se ne koriste izravno u predlošcima putem svog selektora moraju se dodati u entryComponents niz modula u @NgModule dekoratoru. Kada otvarate modal u Bootstrapu, zapravo ne koristite selektor komponente nigdje, pa je vaš SignInComponent jedan takav primjer.
Ti bi učinio nešto ovako
@NgModule({
//...
declarations: [
SignInComponent,
],
entryComponents: [
SignInComponent,
]
})
export class LazyLoadedModule {
}
označiti komponentu za kompilaciju iako nije referencirana u predlošku nijedne druge komponente putem svog selektora.
Više o ulaznim komponentama, kako one rade i zašto ih trebate deklarirati na ovaj način možete pročitati u službenoj Angular dokumentaciji ovdje. Kao i u ovom StackOverflow postu.
Odgovor #2
Evo kako sam uspio učiniti ono što ti želiš. Ideja je da, budući da je login komponenta u ljepljivom modulu, budući da ljepljivi moduli se učitavaju pomoću rutera prilikom navigacije na neke rute, potrebno je navigirati unutar modala na rutu koja učitava ljepljivi modul i prikazuje login komponentu. I to se može učiniti pomoću imenovanog router outlet-a. Nisam baš iskusan s imenovanim router outlet-ima, pa možda postoji nekoliko stvari za doraditi, ali čini se da radi.
Dakle, pretpostavljajući da imate lijeni modul LoginModule s rutom praznog puta koja prikazuje komponentu za prijavu, evo kako se mogu definirati rute glavnog modula:
export const ROUTES: Routes = [
{
path: '',
component: HomeComponent
},
{
path: 'login',
loadChildren: './login/login.module#LoginModule'
},
{
path: 'modal-login',
component: ModalLoginShellComponent,
outlet: 'modal',
children: [
{
path: '',
loadChildren: './login/login.module#LoginModule'
}
]
}
];
Komponenta početne stranice imala bi poveznicu koja omogućuje otvaranje ModalLoginComponent unutar modala (kao što je prikazano u ng-bootstrap primjeru). Predložak ove ModalLoginComponent izgledao bi ovako:
<div class="modal-header">
<h4 class="modal-title">Hi there!</h4>
<button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross click')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<router-outlet name="modal"></router-outlet>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-dark" (click)="activeModal.close('Close click')">Close</button>
</div>
Važan dio je
<router-outlet name="modal"></router-outlet>
Omogućuje, unutar modalnog prozora, navigaciju do rute, i posebno, do rute koja bi učitala lijeno učitani modul.
Kod ModalLoginComponent-a imao bi sljedeći ngOnInit(), koji bi pokrenuo navigaciju:
ngOnInit() {
this.router.navigate([{outlets: {'modal': ['modal-login']}}]);
}
Ovo bi tako učitalo ModalLoginShellComponent i njegovu zadanu, na zahtjev učitanu dječju rutu unutar tijela modala. ModalLoginShellComponent je glupa komponenta koja ništa ne radi, i samo ima, kao svoj predložak
<router-outlet></router-outlet>
