У меня есть ряд директив, которые я хотел бы скомпилировать и прикрепить к DOM. Например:
mod.controller("ctrl, ["$scope", "$compile", function($scope, $compile) {
$scope.tools = [
{
title: "foo",
directive: $compile("<foo-bar></foo-bar>")($scope)
},
{
title: "qux",
directive: $compile("<qux-bar></qux-bar>")($scope)
}
...
];
Затем в HTML:
<div ng-repeat="tool in tools">
<div class="tool">
<h3>{{tool.title}}</h3>
{{tool.directive}}
</div>
</div>
Я хотел бы, чтобы каждая директива была скомпилирована и введена в DOM. Но ничего не происходит. Я ожидаю, потому что слишком поздно звоню в $compile
. Есть лучший способ сделать это?
FWIW, если я скомпилирую директиву и "вручную" добавлю ее в DOM, она работает:
$('body').append($compile('<foo-bar></foo-bar>')($scope));
Вы не можете сделать это таким образом; {{...}}
привязки не принимают элементы. Их можно заставить принимать HTML, но этот HTML статичен - не скомпилирован.
Если вам нужны динамические директивы, вы должны сделать это сами. Один из вариантов имеет вспомогательную директиву, например, директиву container-directive
ниже:
<div class="tool" container-directive>
<h3>{{tool.title}}</h3>
<placeholder style="display: none"></placeholder>
</div>
Он берет tool
из контекста, $compile
его и заменяет элемент фиктивного заполнителя. Предположим, что tools
определены как:
this.tools = [
{ title: 'foo', directive: 'foo-bar' },
{ title: 'qux', directive: 'qux-bar' }
];
Тогда очень простая реализация:
app.directive('containerDirective', function($compile) {
return {
restrict: 'A',
link: function(scope, elem, attrs) {
elem.find('placeholder')
.replaceWith($compile('<' + scope.tool.directive + '></' + scope.tool.directive + '>')(scope));
}
};
});
См. Скрипку: http://jsfiddle.net/kxj60cbo/
Этот код демонстрирует общую идею. Это определенно потребует некоторой корректировки в соответствии с вашими потребностями. Например, директива тесно связана с именем переменной итерации - tool
- возможно, использование изолированной области будет лучше.
Я бы не вводил, я бы просто определил, что показывать
<div ng-repeat="tool in tools">
<div class="tool">
<h3>{{tool.title}}</h3>
<foo-bar ng-if="tool.title = 'foo'"></foo-bar>
<qux-bar ng-if="tool.title = 'qux'"></qux-bar>
</div>
</div>