Angular Material is a project from the angular team with the aim of creating a set of high quality of UI components based on the Googles material design specification and this library is used by many applications both inside and outside of Google.
The main purpose of Component Dev Kit (CDK) is to bridge tooling for developers particularly component authors to create there own custom components without having to reinvent the wheel for common interaction patterns and behaviors. The CDK is broken up into multiple different sub packages each with a single responsibility and a purpose. We are going to look about portals here.
“The portals package provides a flexible system for rendering dynamic content into an application.” — Material Angular
Basically what it does is, it help us to render the piece of UI dynamically to an open slot on the page. To know more about portal follow this documentation.
Let’s take an example of an angular app, where we are using navbar which has different menus on the right and the company name on its left. The app consists of different views which are mapped by the router with respected pages.
Now, when we click the support we need to show login button on the right side of the support menu.
We need to render a dynamic piece of content on support the page, which is login button in this case. If we wanted to render this component in a DOM element running outside the Angular context we locate a Node in the DOM to insert the component, then leverage the ComponentFactoryResolver to generate a new instance of the component. If you’re unfamiliar with this technique Maxim Koretskyi has a great article on this topic. You can also check out the Angular documentation.
Once the component is created we need to add the component to the application’s component tree.
The downside to this approach is we’ve only handled one simple case. What if we wanted to instead create an embedded template instead of a component? What if we wanted to provide a different ViewContainerRef?
let’s use portals
To use portals we need to distinguish its concepts:
Portal a component (ComponentPortal), or an embedded template (TemplatePortal) you would like to display.
PortalHost which is the so-called “open slot” where we want to render our dynamic content, think as a placeholder a component or template will be inserted into.
For our scenario, we use TemplatePortal, which allows us to reference a TemplateRef. Then we want to define some arbitrary DOM element (i.e. a <div>) where we want to place our <ng-template>. For that usecase, we can use DomPortalHost . For more documentation read here.
Now, let’s define where we want to render our dynamic content.
let’s create a reusable component called ActionComponent which is defined as follows.
We now need to get a reference to our template. We can create a TemplatePortal to be attached to our portal host. Once we have our reference to the template, we can instantiate, and pass it the reference. We can even optimize this by using the cdkPortal directive directly, rather than a simple template variable.
We’re ready to attach the portal to the host, or better said, to render the dynamic template into the <div id="action"> which is controlled by the DomPortalHost we created before. Now in our support view page we can reuse our ActionComponent created before.
Now, if you navigate the route to the support page you can see login button over there on our navbar.