Dynamically add directives in AngularJS

For a walkthrough see http://blog.fourtonfish.com/post/74055065673/dynamically-add-directives-in-angularjs-no-jquery

by toddhd

HTML

<section ng-app="app" ng-controller="MainCtrl">
  <person ng-repeat="p in people"></person>
  <container ng-repeat="c in containers"></container>
</section>

CSS

section {
  padding: 2em;
}

div {
  margin-top: 1em;
}

JavaScript

var app = angular.module('app', []);

app.directive("person", function() {
  return {
    restrict: "E",
    //    scope: {
    //        done: "&"
    //      },
    template: '<div><a href ng-click="setContainers(p.id)">{{ p.name }}</a></div>'
  };
});

app.directive("container", function() {
  return {
    restrict: "E",
    //    scope: {
    //        done: "&"
    //      },
    template: '<div>{{ c.name }}<detail ng-repeat="d in details"></detail></div>'
  };
});

app.directive("detail", function($compile) {
  return {
    link: function(scope, element, attrs) {
      if (scope.d.elementType === 'label') {
        var html = '<div><label>{{ scope.d.name }}</label></div>';
        var template = angular.element(html);
        element.append(template);
        $compile(template)(scope);

      } else {
        var html = '<div><input value="scope.d.value"></input></div>';
        var template = angular.element(html);
        element.append(template);
        $compile(template)(scope);

      }
    }
  };
});



function MainCtrl($scope) {

  $scope.people = [];
  $scope.containers = null;

  $scope.setContainers = function(id) {
    $scope.containers = $scope.people[id].containers;
  }

  function person(id, name) {
    this.id = id;
    this.name = name;
    this.containers = [];
    this.containers.push(new container(0, name + 's Container 0'));
    this.containers.push(new container(1, name + 's Container 1'));
    this.containers.push(new container(2, name + 's Container 2'));
    this.containers.push(new container(3, name + 's Container 3'));

  }

  function container(id, name) {
    this.id = id;
    this.name = name;
    this.details = [];
    if (id === 0) {
      this.details.push(new detail('Last Name', '', 'label'));
      this.details.push(new detail('', 'Davis', 'text'));
    }
    if (id === 1) {
      this.details.push(new detail('Gender', '', 'label'));
      this.details.push(new detail('', 'Female', 'text'));
    }
    if (id === 2) {
    ...