Как динамически загружать директиву в страницу

У меня есть html файл с контроллером и директива с шаблоном url. Я хочу загрузить/скомпилировать директиву условно в контроллере:

Контроллер:

app.controller('TestController', function TestController($http, $scope, $compile) {

$scope.loadData = function (pageId) {
    var pUrl = <some url>
    $http({
        method: 'GET',
        url: pUrl
    }).success(function (data, status) {
        $scope.pData = data;
        var htm = '<test-directive></test-directive>';
        var elm = angular.element("#id").append(htm);
        $compile(elm)($scope);
    }).error(function (data, status) {
        alert('error');
    });
};

$scope.loadData();

});

Директива

'use strict';

app.directive('testdirective', function ($http) {
var uDirective = {};

uDirective.restrict = 'E';
uDirective.templateUrl = 'js/directives/testdirective.html';
uDirective.controller = function ($scope, $element, $attrs) {
$scope.showDirectiveData();

    $scope.showDirectiveData = function () {
        $scope.directiveDataCollection = <get data>;
    };
};

uDirective.compile = function (element, attributes) {
    // do one-time configuration of element.

    var linkFunction = function ($scope, element, atttributes) {
    };

    return linkFunction;
};

return uDirective;
});

Шаблон, используемый в директиве

<div>
   <div ng-repeat="directiveData in directiveDataCollection">
      <span><h4>{{directiveData.Title}}</h4></span>
   </div>
</div>

Как я могу скомпилировать код в TestController, динамически загружать директиву и, наконец, загружать содержимое и добавлять содержимое в область видимости?

Ответ 1

Вот общий шаблон для ссылки на тезисы, а также демонстрирует несколько концепций Angular:

JS

.directive('parentDirective', function(Resource, $compile){
  return {
    restrict: 'E',
    link: function(scope, elem, attrs){
      Resource.loadData().then(function(result){
        scope.data = result.data;
        var htm = '<child-directive></child-directive>';
        var compiled = $compile(htm)(scope);
        elem.append(compiled);
      });
    }
  }
})
.directive('childDirective', function(){
  return {
    restrict: 'E',
    template: '<div>Content: {{data.key}}</div>'
  }
})
.factory('Resource', function($http){
  var Resource = {};

  Resource.loadData = function(){
    return $http.get('test.json');
  }

  return Resource;
})

HTML

<body ng-app="myApp">
  <parent-directive></parent-directive>
</body>

Обратите внимание, что код контроллера отсутствует. Это связано с тем, что контроллеры никогда не должны манипулировать DOM - одна из причин заключается в том, что он сделает ваш код PITA для тестирования. Итак, я помещаю все в директивы, где это, вероятно, должно быть и в вашем случае.

Я также перевел службу $http в factory. Любое состояние/модель должна быть в сервисе. Среди других причин, делая это, вы можете вводить его практически в любом месте (в том числе внутри директив) для доступа к своим данным, не беспокоясь о том, что он исчезает при выгрузке контроллера.

ИЗМЕНИТЬ

Вы также должны рассмотреть несогласие взгляда на подход динамической загрузки вообще в принятом ответе Динамическое добавление директив Angular