Saved By The Aurelia Portal Attribute

Last updated: February 19, 2019

Recently at my day job, I encountered a very specific scenario that I wrestled with for quite a bit. I had a routed set of views, which were using a layout view template because it needed a very specific markup for positioning using CSS Grid.

The issue I had was although the route layout had a <slot></slot> element inside of it for projecting the routes, I wanted a custom navigation element to be projected inside of the routed view. Previously there was a bit of duplication to add the custom element into the right area.

I initially tried to use router View Ports to achieve the result I needed, but they’re more designed for rendering sub-views within a view, I needed to render a component into a specific area of the page and have it react to route change events.

Then I remember the Portal attribute by core team member Binh Vo, it has actually been around for a while now. I haven’t had a need for this plugin, until now. In my situation, I needed to leverage the target property of the attribute to tell it where to inject my custom element and everything worked as expected.

My layout view simplified looks like this:

<section>
    <main-nav></main-nav>
    <inner-nav portal="target: #nav-slot;"></inner-nav>
    <slot></slot>
</section>

For each routed view the simplified markup looks like this:

<template>
  <main>
    <div class="dashboard-wrapper">
      <div class="inner-content">
        <section>
          <div id="nav-slot">
            <div class="content">
                <h1>Some content</h1>
            </div>
          <div>
        </section>
      </div>
    </div>
  </main>
</template>

When this routed view is loaded, the portal attribute will inject the element from the router layout into the DIV with the ID nav-slot. Super simple stuff and it does exactly what I needed it to do. The portal plugin can be found on GitHub here and it’s great to see how it all functions behind-the-scenes. A demo of the plugin in action can also be found here.

 

Dwayne

 

Leave a Reply

Your email address will not be published. Required fields are marked *