Reputation: 39364
I am creating an Angular's 7 ModalService that simply opens a Modal (StackBlitz Example).
The Modal content should be a Component passed to the Modal when opening.
Modal
export class Modal {
protected modal: any = null;
close() {
this.modal.close();
}
}
ModalService
import { ApplicationRef, ComponentFactoryResolver, EmbeddedViewRef, Injectable, Injector } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class ModalService {
private componentRef: any;
private modalContainer: any;
constructor(
private componentFactoryResolver: ComponentFactoryResolver,
private appRef: ApplicationRef,
private injector: Injector) { }
private createFormModal(component: any): Element {
this.componentRef = this.componentFactoryResolver.resolveComponentFactory(component.component).create(this.injector);
this.componentRef.instance.modal = this;
this.appRef.attachView(this.componentRef.hostView);
return (this.componentRef.hostView as EmbeddedViewRef<any>).rootNodes[0] as HTMLElement;
}
open(component: any): void {
const alertElement = this.createFormModal(component);
const content = document.createElement('div');
content.classList.add('modal');
content.appendChild(alertElement);
this.modalContainer = document.createElement('div');
this.modalContainer.classList.add('modal');
this.modalContainer.appendChild(content);
document.body.appendChild(this.modalContainer);
}
close(): void {
this.appRef.detachView(this.componentRef.hostView);
this.modalContainer.parentNode.removeChild(this.modalContainer);
this.componentRef.destroy();
}
}
I am not sure if this is the best option but it is not working ...
When I try to open the modal I get the following error:
Error: No component factory found for HelloComponent.
Did you add it to Did you add it to @NgModule.entryComponents?
What am I missing? And can I improve this ModalService code?
Upvotes: 2
Views: 3191
Reputation: 11
Add HelloComponent
in entry component of @NgModule
:
@NgModule({
imports:[ BrowserModule, FormsModule ],
declarations:[ AppComponent, HelloComponent ],
entryComponents:[HelloComponent],
bootstrap: [ AppComponent ]
})
export class AppModule { }
Upvotes: 1
Reputation: 5962
As the error suggests , you need to add the component in the entryComponents
array of your root module app.module.ts
if you need to render the component as the modal content. This is required because as per the angular documentation if you are dynamically loading a component by type imperatively(using ComponentFactoryResolver
) then you need to add that component in the entryComponents
array of your root module.
Because these components are not referenced in your angular app by template or by selector.
So your app.module.ts
should look like this -
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { HelloComponent } from './hello.component';
@NgModule({
imports: [ BrowserModule, FormsModule ],
declarations: [ AppComponent, HelloComponent ],
entryComponents:[HelloComponent],
bootstrap: [ AppComponent ]
})
export class AppModule { }
Here is the updated stackblitz demo -
https://stackblitz.com/edit/mk-angular-modal-service-6qhrps
Here is more information on entryComponents
https://angular.io/guide/entry-components
There are still some css issue in your modal which needs to be fixed.
Upvotes: 6