title: Dynamically bind model and template to at DOM node in Angular 2
body: <h2>Short version</h2>
  <p>This <a href="http://plnkr.co/edit/BH7SFTnFcQ9gQEwc5dmc?p=preview" rel="nofollow noreferrer">Plunker</a> defines a <code>&lt;view&gt;</code> component which can render an arbitrary model+template. This needs to be changed to <em>replace</em> the previously rendered contents rather than appending new peers.</p>
  <p>EDIT: This is working now, thanks to the response by user3636086.</p>
  <p>One problem still remains: unlike Angular 1, Angular 2 forces me to create a nested component to update a template (since templates are effectively a static property of a component's <em>class</em>), so I have a bunch of unnecessary DOM nodes being added.</p>
  <hr />
  <h1>Long Version</h1>
  <h3>Angular 1</h3>
  <p>In our project we'd prefer <em>most</em> of our code to have no direct dependency on a UI framework. We have a viewmodel class which ties together a model and view. Here are simplified examples:</p>
  <pre><code>interface IView {
      template: string;
  }
  
  class SalesView implements IView  {
      sales: number = 100;
      get template() { return &quot;&lt;p&gt;Current sales: {{model.sales}} widgets.&lt;p&gt;&quot;; }
  }
  
  class CalendarView implements IView {
      eventName: string = &quot;Christmas Party&quot;;
      get template() { return &quot;&lt;p&gt;Next event: {{model.eventName}}.&lt;p&gt;&quot;; }
  }
  
  class CompositeView implements IView  {
      calendarView = new CalendarView();
      salesView = new SalesView();
      get template() { return 
          `&lt;div view='model.salesView'&gt;&lt;/div&gt;
          &lt;div view='model.calendarView'&gt;&lt;/div&gt;`; 
      }
  }
  </code></pre>
  <p>We have a <code>view</code> directive that can display one of these views:</p>
  <pre><code>&lt;div view='viewInstance'&gt;&lt;/div&gt;
  </code></pre>
  <p>If <code>viewInstance</code> changes, a new View object is rendered (model + template) at that location in the DOM. For instance, this Dashboard view can have an arbitrary list of views that it can render:</p>
  <pre><code>class Dashboard implements IView {
      views: Array&lt;IView&gt; = [ new SalesView(), new CalendarView(), new CompositiveView() ];
      activeView: View;
      get template() { return &quot;&lt;h1&gt;Dashboard&lt;/h1&gt;  &lt;div view='model.activeView'&gt;&quot;; }
  }
  </code></pre>
  <p><strong>A crucial point is that this is composable. The <code>&lt;view&gt;</code> can contain a <code>&lt;view&gt;</code> which can contain a <code>&lt;view&gt;</code>, so on and so forth.</strong></p>
  <p>In Angular 1, our <code>view</code> directive looks something like this:</p>
  <pre><code>.directive(&quot;View&quot;, [ &quot;$compile&quot;,
      ($compile: ng.ICompileService) =&gt; {
          return &lt;ng.IDirective&gt; {
              restrict: &quot;A&quot;,
              scope: { model: &quot;=View&quot; },
              link(scope: ng.IScope, e: ng.IAugmentedJQuery, atts: ng.IAttributes): void {
                  scope.$watch((scope: any) =&gt; scope.model, (newValue: any) =&gt; {
                      e.html(newValue.template);
                      $compile(e.contents())(scope.$new());
                  });
              }
          };
      }
  ]);
  </code></pre>
  <h3>Angular 2</h3>
  <p>I'm trying to port this to Angular 2, but dynamically loading a new template at a DOM location is very clunky, forcing me to create a new component type every time.</p>
  <p>This is the best I've come up with (updated with feedback from user3636086):</p>
  <pre><code>@Component({
    selector: 'view',
    template: '&lt;span #attach&gt;&lt;/span&gt;',
  })
  export class MyView {
      @Input() model: IView;
  
      previousComponent: ComponentRef;
  
      constructor(private loader: DynamicComponentLoader, private element: ElementRef) {
      }
  
      onChanges(changes: {[key: string]: SimpleChange}) {
          var modelChanges = changes['model']
          if (modelChanges) {
              var model = modelChanges.currentValue;
              @Component({
                  selector: 'viewRenderer',
                  template: model.template,
              })
              class ViewRenderer {
                  model: any;
              }
              if (this.previousComponent) {
                  this.previousComponent.dispose();
              }
              this.loader.loadIntoLocation(ViewRenderer, this.element, 'attach')
                  .then(component =&gt; {
                      component.instance.model = model;
                      this.previousComponent = component;
                  });
          }
      }
  }
  </code></pre>
  <p>Used something like this:</p>
  <pre><code>@Component({
      selector: 'app',
      template: `
          &lt;view [model]='currentView'&gt;&lt;/view&gt;
          &lt;button (click)='changeView()'&gt;Change View&lt;/button&gt;
      `,
      directives: [MyView]
  })
  export class App {
      currentView: IView = new SalesView();
      changeView() {
          this.currentView = new CalendarView();
      }
  }
  </code></pre>
  <p>EDIT: This <em>had</em> problems that have now been fixed.</p>
  <p>The remaining problem is that it creates a bunch of unnecessary nested DOM elements. What I really want is:</p>
  <pre><code>&lt;view&gt;VIEW CONTENTS RENDERED HERE&lt;/view&gt;
  </code></pre>
  <p>Instead we have:</p>
  <pre><code>&lt;view&gt;
        &lt;span&gt;&lt;/spawn&gt;
        &lt;viewrenderer&gt;VIEW CONTENTS RENDERED HERE&lt;/viewrenderer&gt;
  &lt;/view&gt;
  </code></pre>
  <p>This gets worse the more views we have nested, without half the lines here being extraneous crap:</p>
  <pre><code>&lt;view&gt;
      &lt;span&gt;&lt;/spawn&gt;
      &lt;viewrenderer&gt;
          &lt;h1&gt;CONTENT&lt;/h1&gt;
          &lt;view&gt;
              &lt;span&gt;&lt;/spawn&gt;
              &lt;viewrenderer&gt;
                  &lt;h1&gt;NESTED CONTENT&lt;/h1&gt;
                  &lt;view&gt;
                      &lt;span&gt;&lt;/spawn&gt;
                      &lt;viewrenderer&gt;
                          &lt;h1&gt;NESTED NESTED CONTENT&lt;/h1&gt;
                      &lt;/viewrenderer&gt;
                  &lt;/view&gt;
              &lt;/viewrenderer&gt;
          &lt;/view&gt;
      &lt;/viewrenderer&gt;
      &lt;viewrenderer&gt;
          &lt;h1&gt;MORE CONTENT&lt;/h1&gt;
          &lt;view&gt;
              &lt;span&gt;&lt;/spawn&gt;
              &lt;viewrenderer&gt;
                  &lt;h1&gt;CONTENT&lt;/h1&gt;
              &lt;/viewrenderer&gt;
          &lt;/view&gt;
      &lt;/viewrenderer&gt;
  &lt;/view&gt;
  </code></pre>