Migrating ASP.Net MVC PartialViews to Angular2

An Angular2 @Component combines the equivalents of MVC Controller and View. This mostly also applies to MVC PartialViews.

In my application, TypeScript dynamically adds PartialViews to the page’s HTML.

Migrating the code to Angular2, the page’s component, let’s call it ParentComponent, contains an array of ChildComponents. If a new ChildComponent is added to the array, Angular2 will automatically render its template or templateURL, and add the resulting HTML inside the <childcomponent> tag

<childcomponent *ngFor="#c of childcomponents" [childdata]="c">

Your custom JavaScript code can then process the rendered component in one of the LifeCycle Hooks.

The story gets more complicated if your code needs to dynamically select which PartialView to render. Of course, there is the NgSwitch directive, which acts as the templating’s switch/case mechanism, but template code may easily get ugly and overly complex.

The alternative is to define the template or templateURL programmatically by calling loader.loadIntoLocation() of DynamicComponentLoader, but, as GitHub issues show (#7815, #6701, #7596, #2753), this is not as straight-forward as one might hope, especially if template data-binding is involved (#6223, #7453SO, SO).

The solution that I extracted from the referenced issues looks like this

constructor(private loader: DynamicComponentLoader, 
    private elementRef: ElementRef, 
    private ref: ChangeDetectorRef) {
  this.myData = ..some data..;
  this.myOtherData = ..some data..;

ngOnInit() {
  var templateURL = .... calculate template ...;

    this.toComponent(templateURL + '.html', null),
    this.elementRef, 'newItem'
  ).then(component => { 
    component.instance.myData = this.myData;
    component.instance.myOtherData = this.myOtherData;

Based on SO and plnkr

toComponent(templateUrl, directives = []) {
  @Component({ selector: 'child-fake-component', 
  templateUrl: templateUrl,
  directives: [COMMON_DIRECTIVES])
  class ChildFakeComponent {}
  return ChildFakeComponent;

Note that I need ChangeDetectorRef to explicitly update the template because I deactivated change detection using ChangeDetectionStrategy.OnPush, so this need not apply to your case.

The essential part is that you need to copy all data referenced by the template to component.instance. #newItem is the anchor of the HTML element in the @Component’s template or template, and the loaded template will be attached after the original template, not replacing the original template.

One Response to Migrating ASP.Net MVC PartialViews to Angular2

  1. […] a component needs to dynamically switch between several available templates, things get a bit complicated, but it’s […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: