Is there a way to dynamically render different templates for an angular 1.5 component

Joe picture Joe · Jul 28, 2016 · Viewed 12.8k times · Source

I have a number of angular 1.5 components that all take the same attributes and data structure. I think they could be re-factored into a single component, but I need a way to dynamically choose a template based upon the interpolated value of the type attribute.

var myComponentDef = {
    bindings: {
        type: '<'
    },
    templateUrl: // This should be dynamic based on interpolated type value
};

angular.module('myModule').component('myComponent', myComponentDef);

I can't use the templateUrl function($element, $attrs) {} because the values in the $attrs are uninterpolated so I wouldn't get the type specified in the passed in data.

I could just have one big template with a series of ng-if or ng-switch directives, but I would like to keep the templates separate.

Alternatively, I could just keep the components separate and use ng-switch etc in the parent component, but I don't like this as it seems like a lot of repetition.

I'm looking for a solution where I can use the interpolated type passed into the bindings to match a template url for each type which will then be used to build the component.

Is this possible?

Thanks

Answer

Estus Flask picture Estus Flask · Jul 29, 2016

This is not something that components were specially made for. The task narrows down to using a directive with dynamic templates. The existing one is ng-include.

To use it within a component, it should be:

var myComponentDef = {
  bindings: {
    type: '<'
  },
  template: '<div ng-include="$ctrl.templateUrl">',
  controller: function () {
    this.$onChanges = (changes) => {
      if (changes.type && this.type) {
        this.templateUrl = this.type + '.html';
      }
    }
  }
}