title: A directive replacing loading content with spinner in Angular 2+
body: <p>In Angular 1, it was fairly easy to create a loading directive that replaced content with a spinner and was used like so:</p>
  
  <pre><code>&lt;div isLoading="$scope.contentIsLoading"&gt;&lt;/div&gt;
  </code></pre>
  
  <p>Where contentHasLoaded is a simple boolean value you set in your controller after a data call. The directive itself, was simple, most of the work being done in a template:</p>
  
  <pre><code>&lt;div class="spinner" ng-if="$scope.isLoading"&gt;&lt;/div&gt;
  &lt;div ng-transclude ng-if="!$scope.isLoading"&gt;&lt;/div&gt;
  </code></pre>
  
  <p>Is there a "clean" way to do this in Angular 2+? By clean I mean 1) within Angular, not using vanilla JS to directly manipulate the DOM and 2) Can be implemented as a single attribute on an existing element?</p>
  
  <p>I did see this article as fallback:<a href="https://stackoverflow.com/questions/43301624/angular-img-loading-directive">Image Loading Directive</a>. However, it's a little more verbose than I would like: using a regular component requires me to wrap all my async content in a new tag rather than just adding an attribute.</p>
  
  <p>What I'm really looking for is something in a structural directive (which are supposed to be designed for "manipulating the DOM.") However, all the examples I've seen are recreations of something like *ngIf, which hides content but does not insert new content. Specifically, can a structural template 1) have a template, or 2) insert a component or 3) insert something as simple as <code>&lt;div class="spinner"&gt;&lt;/div&gt;</code>. Here's my best attempt so far:</p>
  
  <pre><code>import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
  
  @Directive({
    selector: '[loading]',
    inputs: ['loading']
  })
  export class LoadingDirective {
  
    constructor(
      private templateRef: TemplateRef&lt;any&gt;,
      private viewContainer: ViewContainerRef
      ) { }
  
    @Input() set loading (isLoading: boolean) {
      if (isLoading) {
        this.viewContainer.clear();
        // INSERT A COMPONENT, DIV, TEMPLATE, SOMETHING HERE FOR SPINNER
      } else {
        this.viewContainer.clear();
        // If not loading, insert the original content
        this.viewContainer.createEmbeddedView(this.templateRef);
      }
    }
  
  }
  </code></pre>