AngularJS directive with multiple templates

Personally I think that Option 2 offers a clean separation between display modes. I have created a working CodePen example to illustrate how you might accomplish this cleanly by using separate directives for each template.

The method I used in my CodePen example utilizes a template factory which is injected into each directive via Angular DI. The template factory implementation is very clean since it merely uses ng-include template strings for each of the different supported display modes (compact & detailed). The actual HTML templates (partials) can be housed in external view files or internal script blocks.

Using the contact directives are easy:

<contact compact ng-repeat="contact in contacts" ng-model="contact"></contact>

This creates a compact version of the contact list.

<contact detailed ng-repeat="contact in contacts" ng-model="contact"></contact>

This creates a detailed contact listing.

I will admit that I haven't deployed code like this to production so there may be scalability or other concerns I haven't considered. I hope the code I provided answers your questions or at least provides inspiration for further exploration.


I have build a new approach working on Adam example and using also the sample from angular docs in which they talk about functions in templateUrl property https://docs.angularjs.org/guide/directive, this is the plunker from angular docs: http://plnkr.co/edit/h2CSf2WqCLYfPvzL9WQn?p=preview

.directive('myCustomer', function() {
    return {
      templateUrl: function(elem, attr){
        return 'customer-'+attr.type+'.html';
      }
    };
  });

And this is my remixed solution:

http://codepen.io/anon/pen/wawOyz?editors=101

app.factory('templates', function() {
  return {
    compact:   'compact',
    detailed:  'detailed'
  };
 });

app.directive('contact', function(templates) {
  return {
    restrict: 'E',
    templateUrl: function($elem, $attr){
      return templates[$attr.mode];       
    },
    scope: {
      contact: '=ngModel'
    }
  };
});

I liked the idea of having all template addresses in one factory but I find the directive-per-mode quite repetitive and if you have several elements using this approach you will need to namespace them (contact-text, email-text, company-text) so they don't crash.

I am not sure yet if this is a better way to go, is shorter and more DRY, but maybe is more difficult to test or less customizable. I just wanted to share the approach in case it can help anyone.