SoFunction
Updated on 2025-04-11

Dynamically create Angular components to implement popup window function

Start: Use ngIf directly

Put the pop-up DOM directly under the page to hide it, and control its display through commands like ngIf.

Improvement: Encapsulated into an angular module, and its display is controlled through services

If you use ngIf directly, the unpleasant thing is that it is not universal enough, and you have to add DOM on each page. If improved, some more general DOMs can be encapsulated into components, added to the global page, and the display control can be handed over to an angular service to control its display.

For example, two components (DialogComponent, AlertComponent) are defined, they are added to the AppComponent, and then a PopupService is provided to control the display of the components and support passing parameters in.

The mode of displaying by controlling only is still not universal enough and there is coupling

The method of encapsulating pop-up components and using services to control displays seems to be more general, but there are two embarrassing problems:

  1. It is still necessary to place a popup component somewhere on the page, such as PopupComponent. This component is responsible for rendering some common popup components hidden by default in order to perform display control to achieve popup capabilities.
  2. If you want a custom window to pop up, you can only go back to the top and write the DOM and place it on the position where the custom popup window needs to pop up, or pass the custom tag into it through the innerHtml command (rich text method).

It can be seen that such pop-up capabilities are not very universal, and pop-up sockets must be placed manually (so called that) so that there is an extra coupling.

Dynamically create pop-up windows

The ideal way should be: when you want a pop-up window to pop up, you can pop up the window with one line of code without writing the pop-up window in advance (or this step should not be done by the user of the pop-up window control, the pop-up window control should automatically complete this).

This capability involves the ability of angular to dynamically create components.

Usage given by the official website

Official angular documentationThere are usages of dynamically creating components. However, it uses the ViewContainerRef service, which provides the createComponent method to dynamically create a component in the specified view container.

However, the embarrassing point of ViewContainerRef is that it can only be used in specific instructions and components. That is to say, it must be told where it plans to create a new component. This still requires the creation of a "pop-up socket" to dynamically create components in this "socket".

So is there any way to create a component without giving a view container. In layman's terms, the problem is: not to create a component in a directive or component, but to create a component in a service, and to let the component be displayed on the page.

Establishing a factory – the real creator of components

Creating the core code of a component in a component is divided into two steps:

Create a component factory

let componentFactory = (Components to be created);

Provide the factory to the container to create components

let componentRef = (componentFactory);

The problem now is that if you cannot get the viewContainerRef in the service, the factory can be created successfully.

In fact, it is enough to have a factory. Check the members provided by componentFactory that contain a create method. As the name suggests, this should be used to create components.

The create method has a required parameter type as Injector, which is the injector, which means what service is intended to inject into the created component. It is no problem to write null directly on the brute force point.

The component that is directly created using the factory is also returned with a reference of type ComponentRef. It can be seen that the component was indeed created at this time, but it has not been inserted into the view yet. You can be more violent at this time and directly insert it to the end of the body tag using the native DOM operation:

(
  (componentRef)
);
(componentRef); // Use after injecting the ApplicationRef service// ...
private getComponentRootNode(componentRef: ComponentRef<any>): HTMLElement {
  return ( as EmbeddedViewRef<any>).rootNodes[0] as HTMLElement;
}
// ...

This method was found by the author from the vast source code of Material2. Google itself plugs it directly, so you can use it with confidence. I have to admire the implementation of the Dialog module in Material2, which is really complicated.

Summarize

This article mainly talks about ideas, and only after the end of the process is to enter the topic to create components dynamically. However, just creating components and adding them to the DOM is only the first step. A robust pop-up module (like Material2) must have a complete set of interactive capabilities, such as subscription and value transmission during pop-up and closing. These must be implemented by injecting services into the component. Due to the limited space, we will return to the actual implementation of a pop-up module implemented by dynamically creating components in the next article.

The above is the dynamic creation of Angular components to implement popup function that the editor introduced to you. I hope it will be helpful to you. If you have any questions, please leave me a message and the editor will reply to you in time. Thank you very much for your support for my website!