A first look into the Angular CDK

Carlos Roso
Jul 16, 2017 · 5 min read

In this post I dive into some of the features included in the recently released Angular CDK. Specifically, I’ll talk about Portal and PortalHost.

TL;DR: I built a simple example using the recently released Angular CDK. Jump to the code at the end of this post or visit the working demo in Stackblitz.

Angular Material CDK

Just as a little bit of introduction, the Angular Material team released a few days ago the Angular Component Development Kit. I won’t put much effort into explaining what the CDK is so I’ll rather quote them here:

The goal of the CDK is to give developers more tools to build awesome components for the web. This will be especially useful for projects that want to take advantage of the features of Angular Material without adopting the Material Design visual language. — Angular Team

So it’s pretty clear that the CDK is comprised of a bunch of services, directives, components, classes, modules, etc to make our lives easier when developing Angular components. In the current first release they included features for accessibility, text directionality, platform detection, and dynamic component instantiation. I’ll be talking specifically about dynamic component instantiation in this post. There’s no documentation yet but you can take a look at the code here. The CDK is released under the @angular/cdk npm package.

The guys behind the CDK are the same guys behind Angular Material. One of the missions of the Angular Material team has been to lay out a pretty good foundation of how to properly build components in Angular taking into account performance, a11y, i18n, scalability, etc. So, after almost 3k issues closed, I’m sure they know a thing or two about how to build good components for the web. Using the CDK is a safe way to ensure you include the best practices into your component production workflow.

Portal and PortalHost

I’ll do my best to explain these two core concepts which are heavily used in the Angular Material library itself. There’s a brief documentation about this subject inside the CDK source code which you can visit here. Simply put, the CDK exposes an API to let you do dynamic component instantiation via Portals and Portal Hosts. It means you can easily inject Components or Templates inside any other element whether it is an ng-template or a plain DOM element (such as document.body) . Let’s break down the concepts of Portal and PortalHost .

Portal: the piece of UI that you want to inject anywhere else. It can be either a Component or TemplateRef.

PortalHost: the place where you want to render the Portal. There’s a specific implementation of the PortalHost called DOMPortalHost which basically lets you attach a Portal to an arbitrary DOM element outside of the Angular application context, such as the document.body .

A Component or Template Ref is attached to a Portal. A portal is then attached to a PortalHost. A PortalHost can be an ng-template or an arbitrary DOM element.

Before we jump into a example of how to use these concepts in a real world scenario, I’d recommend you to visit the portal.ts implementation inside the CDK source here. Do not try to understand the specific implementation details (do it if you want) but instead take a look at the classes and their methods. You’ll be quick to grasp what each class and method does by just reading their names. This will give you a good feeling of what these utilities do for you.

Example

In this example we’re going to build a simple service/component that lets us show a full width/height Loading… message. This really comes in handy when you load data from an API in several screens. The following code snippets assume the CDK has been installed via npm install @angular/cdk .

We’ll be appending a component into the <body> of our document so the following code will make a lot more sense if you can first take a look at the vanilla, non-cdk approach in this post.

First thing we should do is to create a component with the Loading… message. It can also have a spinner, a shadowed backdrop, fade in/out animation, etc. As this is not the core of this post, I’ll assume you already know how to do that and I’ll skip the implementation details here. The one thing that you should take care of is to add your component to your module’s entryComponents. For the sake of the example, let’s name our component LoadingSpinnerComponent .

This is where we apply the concepts learned in this post. We’ll build a service LoadingSpinnerService that exposes two simple methods: reveal() and hide() which will reveal and hide our loading spinner, respectively (duh).

I really feel that the code is pretty much self explanatory but I’ll add some remarks anyways. Please follow the numbers in the snippet comments:

  1. Create a reference to the Portal: As mentioned earlier, the portal is the abstraction used to contain a Component or TemplateRef. In this case, we’ll have a Portal built from our previously created LoadingSpinnerComponent.
  2. Create a reference to the PortalHost: We’ll be using the document.body to inject our component. We chose a DOM element as the host’s anchor so we use theDomPortalHost implementation of PortalHost .
  3. Inject dependencies: These dependencies are needed by the DomPortalHost to build a PortalHost. If you want to understand what the CDK does with all these dependencies, visit this post in which I go through all these specific details.
  4. Create Portal: There are two implementations of the Portal abstract class: ComponentPortal and TemplatePortal . We use the former as our constructor because we want to create a Portal based on our LoadingSpinnerComponent .
  5. Create PortalHost: Same as point 4, we use the constructor to build a PortalHost based on a DOM element, the <body> . If you’re wondering why I chose the document.body to attach the component, the reason is simple: the loading spinner is a component that should be placed on top of any other element in the screen and we don’t want to be dealing with stacking issues if placed inside any other element. Besides, it works as a dialog so, by architecture, it shouldn’t be part of any component’s descendants.
  6. Reveal the spinner: Show the component by simply attaching it to the PortalHost. Simple as that.
  7. Hide the spinner: Hide the component by simply detaching it from the PortalHost. Simple as that.

Working demo (credits to Gethin Oakes): https://stackblitz.com/edit/angular-cdk-portal-basic.

I hope this post inspires you to go and play with the new Angular CDK. The Angular Material team will for sure be adding more features to the CDK in the upcoming weeks so stay tuned.

If you liked this please show some love and share. Reach out to me at Twitter @caroso1222.

HackerNoon.com

#BlackLivesMatter

HackerNoon.com

Elijah McClain, George Floyd, Eric Garner, Breonna Taylor, Ahmaud Arbery, Michael Brown, Oscar Grant, Atatiana Jefferson, Tamir Rice, Bettie Jones, Botham Jean

Carlos Roso

Written by

Software Engineer. Digital Nomad @toptal. Occasional Designer. I write about remote work, software and personal growth.

HackerNoon.com

Elijah McClain, George Floyd, Eric Garner, Breonna Taylor, Ahmaud Arbery, Michael Brown, Oscar Grant, Atatiana Jefferson, Tamir Rice, Bettie Jones, Botham Jean

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store