How to render asp.net mvc view into angular 2?

I came up with a solution that satisfied my needs at the time. I'm using angular-cli with WebPack, and this worked for my needs. I don't understand all the examples I've seen that say to use "templateUrl: '/Template/Index'", where the path is a path to an MVC view. That simply doesn't work because the path can't be found inside any of the bundled views that WebPack creates. Maybe those people aren't using angular-cli and WebPack.

This stackoverflow answer - How can I use/create dynamic template to compile dynamic Component with Angular 2.0? was very helpful in creating the following directive. This directive will take the output of an mvc partial view and compile it. It allows for Razor/server logic to take place, and some angular to be compiled as well. Although, actually including other components inside this MVC partial was problematic. If you get that working, please let me know what you did. In my case, I just needed the server rendering to happen and to place that exactly where I wanted it in my Angular 2 spa.

MvcPartialDirective

import {
  Component,
  Directive,
  NgModule,
  Input,
  ViewContainerRef,
  Compiler,
  ComponentFactory,
  ModuleWithComponentFactories,
  ComponentRef,
  ReflectiveInjector, OnInit, OnDestroy
} from '@angular/core';

import { RouterModule }  from '@angular/router';
import { CommonModule } from '@angular/common';
import {Http} from "@angular/http";
import 'rxjs/add/operator/map';

export function createComponentFactory(compiler: Compiler, metadata: Component): Promise<ComponentFactory<any>> {
  const cmpClass = class DynamicComponent {};
  const decoratedCmp = Component(metadata)(cmpClass);

  @NgModule({ imports: [CommonModule, RouterModule], declarations: [decoratedCmp] })
  class DynamicHtmlModule { }

  return compiler.compileModuleAndAllComponentsAsync(DynamicHtmlModule)
    .then((moduleWithComponentFactory: ModuleWithComponentFactories<any>) => {
      return moduleWithComponentFactory.componentFactories.find(x => x.componentType === decoratedCmp);
    });
}

@Directive({ selector: 'mvc-partial' })
export class MvcPartialDirective implements OnInit, OnDestroy {
  html: string = '<p></p>';
  @Input() url: string;
  cmpRef: ComponentRef<any>;

  constructor(private vcRef: ViewContainerRef, private compiler: Compiler, private http: Http) { }

  ngOnInit() {
    this.http.get(this.url)
      .map(res => res.text())
      .subscribe(
        (html) => {
          this.html = html;
          if (!html) return;

          if(this.cmpRef) {
            this.cmpRef.destroy();
          }

          const compMetadata = new Component({
            selector: 'dynamic-html',
            template: this.html,
          });

          createComponentFactory(this.compiler, compMetadata)
            .then(factory => {
              const injector = ReflectiveInjector.fromResolvedProviders([], this.vcRef.parentInjector);
              this.cmpRef = this.vcRef.createComponent(factory, 0, injector, []);
            });
        },
        err => console.log(err),
        () => console.log('MvcPartial complete')
      );

  }

  ngOnDestroy() {
    if(this.cmpRef) {
      this.cmpRef.destroy();
    }
  }
}

in some-component.html (assuming your mvc app shares the domain with your spa)

<mvc-partial [url]="'/stuffs/mvcstuff'"></mvc-partial>

MvcStuff.cshtml

@{
    ViewBag.Title = "This is some MVC stuff!!!";
}
<div>
    <h2>MVC Stuff:</h2>
    <h4>@ViewBag.Title</h4>
    <h2>Angular Stuff:</h2>
    <h4>{{1 + 1}}</h4>
</div>

in StuffsController.cs

public PartialViewResult MvcStuff() => PartialView();