Чтобы использовать динамические директивы , вы можете создать пользовательскую директиву, как я делал в этом plunkr:
https://plnkr.co/edit/n9c0ws?p=preview
Вот код нужной директивы:
app.directive('myProxy', function($compile) {
return {
template: '<div>Never Shown</div>',
scope: {
type: '=',
arg1: '=',
arg2: '='
},
replace: true,
controllerAs: '$ctrl',
link: function($scope, element, attrs, controller, transcludeFn) {
var childScope = null;
$scope.disable = () => {
// remove the inside
$scope.changeView('<div></div>');
};
$scope.changeView = function(html) {
// if we already had instanciated a directive
// then remove it, will trigger all $destroy of children
// directives and remove
// the $watch bindings
if(childScope)
childScope.$destroy();
console.log(html);
// create a new scope for the new directive
childScope = $scope.$new();
element.html(html);
$compile(element.contents())(childScope);
};
$scope.disable();
},
// controller is called first
controller: function($scope) {
var refreshData = () => {
this.arg1 = $scope.arg1;
this.arg2 = $scope.arg2;
};
// if the target-directive type is changed, then we have to
// change the template
$scope.$watch('type', function() {
this.type = $scope.type;
refreshData();
var html = "<div " + this.type + " ";
html += 'data-arg1="$ctrl.arg1" ';
html += 'data-arg2="$ctrl.arg2"';
html += "></div>";
$scope.changeView(html);
});
// if one of the argument of the target-directive is changed, just change
// the value of $ctrl.argX, they will be updated via $digest
$scope.$watchGroup(['arg1', 'arg2'], function() {
refreshData();
});
}
};
});
Общая идея:
- мы хотим, чтобы
data-type
мог указывать имя директивы для отображения
- другие объявленные аргументы будут переданы целевым директивам.
- во-первых, в ссылке мы объявляем функцию, способную создать подкаталог с помощью $ compile. 'link' вызывается после контроллера, поэтому в контроллере вы должны вызывать его асинхронно (в $ watch)
- во вторых, в контроллере:
- если
type
директивы изменяется, мы переписываем html, чтобы вызвать target-директиву
- если обновляются другие аргументы, мы просто обновляем $ ctrl.argX, и angularjs запускает $ watch в дочерних элементах и корректно обновляет представления.
Эта реализация в порядке, если все ваши целевые директивы имеют одинаковые аргументы. Я не пошел дальше.
Если вы хотите сделать его более динамичной, я думаю, вы могли бы установить scope: true
и использовать атрибуты, чтобы найти аргументы для передачи директиве target.
Кроме того, вы должны использовать такие шаблоны, как https://www.npmjs.com/package/gulp-angular-templatecache, чтобы преобразовать ваши шаблоны в код, который вы можете объединить в своем приложении javascript. Это будет намного быстрее.