Я пытаюсь внедрить 2 шаблонов в элемент и работать на них:AngularJS: несколько директив с включением на тот же элемент
<div
ic-first="foo"
ic-second="bar"
ic-third="baz"
ic-fourth="qux"
>
</div>
icFirst следует вводить с помощью шаблона пустого DIV как ребенок его элемент. icSecond должен вводить второй DIV (с кучей контента) в качестве второго ребенка его элемента, поэтому результирующий HTML будет выглядеть следующим образом:
<div
ic-first="foo" // priority: 100
ic-second="bar" // priority: 50
ic-third="baz" // priority: 0
ic-fourth="qux" // priority: 0
>
<div id="foo"></div>
<div> <!-- a bunch of stuff from the templateUrl --> </div>
</div>
Оба icFirst и icSecond будут инъекционные другие элементы во вновь созданные контейнеры.
Когда я определяю свойство шаблона директивы по обе директивы, я получаю сообщение об ошибке:
Error: Multiple directives [icFirst, icSecond] asking for template on:
<div ic-first
…
Когда я добавляю transclude: true
в обеих директив, icFirst выполняет просто отлично ... но тогда другие директивы на том же элемент не выполняется. Когда я устанавливаю transclude: 'element'
, другие директивы выполняют , но Я получаю сообщение об ошибке, что первый ребенок ($scope.firstObj
) не определен.
Всех четыре директивы должны иметь доступ к охвату друг друга, так что я делаю большую часть своей работы в своих контроллерах:
app.directive('icFirst', ['ic.config', function (icConfig) {
return {
restrict: 'A',
priority: 100,
template: '<div id="{{firstId}}"></div>',
replace: false,
transclude: 'element',
controller: function icFirst($scope, $element, $attrs) {
// …
$scope.firstId = $scope.opts.fooId;
$scope.firstElm = $element.children()[0];
$scope.firstObj = {}; // this is used by the other 3 directives
},
link: function(scope, elm, attrs) { … } // <- event binding
}
);
app.directive('icSecond', ['ic.config', function (icConfig) {
return {
restrict: 'A',
priority: 0,
templateUrl: 'views/foo.html',
replace: false,
transclude: 'element',
controller: function icSecond($scope, $element, $attrs) {
// …
$scope.secondElm = $element.children()[1];
$scope.secondObj = new Bar($scope.firstObj);
//^is used by the remaining 2 directives & requires obj from icFirst
},
link: function(scope, elm, attrs) { … } // <- event binding
}
);
Примечания я исправил поведение replace: false
в соответствии с документированным поведением, как описано в запросе на растяжение #2433.
Я попытался создать экземпляр $scope.firstObj
в контроллере и установить его в linkFn (надеясь, что завершение будет завершено к моменту выполнения linkFn), но я получаю ту же проблему. По-видимому, первый ребенок - это комментарий.
Теперь есть более простой способ.Просто добавьте '$$ tlb: true' в свою директиву, и он обходит утверждение. –
@JonathanRowny '$$' указывает, что '$$ tlb' является 'private' для API и не должен использоваться за пределами API, так как разработчики могут решить сломать его в любое время. –