Сроки использования функций (pre/post) в AngularJS хорошо определены в документации
Функция предварительной привязки
Выполняется до привязки дочерних элементов. Не безопасно делать DOM преобразование, поскольку функция связывания компилятора не сможет найти правильные элементы для соединения.
Функция постсвязывания
Выполняется после того, как дочерние элементы связаны. Безопасно делать DOM преобразование в функции постсвязывания.
и это сообщение в блоге ясно иллюстрирует этот ожидаемый порядок.
Но этот порядок не применяется при использовании ng-transclude
и вложенных директив.
Вот пример элемента управления (См. Plunkr)
// index.html
<dropright>
<col1-item name="a">
<col2-item>1</col2-item>
<col2-item>2</col2-item>
</col1-item>
<col1-item name="b">
...
</dropright>
// dropright-template.html
<div id="col1-el" ng-transclude></div>
<div id="col2-el">
<!-- Only angularJS will put elements in there -->
</div>
// col1-item-template.html
<p ng-transclude></p>
// col2-item-template.html
<div ng-transclude></div>
Сводка выглядит как
Директивы записывают журнал в консоль, когда вызывается их связь и функции контроллера. Обычно он отображает:
Но иногда (после нескольких обновлений) порядок не соответствует ожиданиям:
Функция прямой передачи по прямой выполняется перед функцией post-link своих дочерних элементов.
Возможно, это связано с тем, что в моем конкретном случае я нахожу контроллер dropright в директивах children (См. Plunkr)
angular.module('someApp', [])
.directive('dropright', function() {
return {
restrict: 'E',
transclude: 'true',
controller: function($scope, $element, $attrs) {
console.info('controller - dropright');
$scope.col1Tab = [];
$scope.col2Tab = [];
this.addCol1Item = function(el) {
console.log('(col1Tab pushed)');
$scope.col1Tab.push(el);
};
this.addCol2Item = function(el) {
console.log('(col2Tab pushed)');
$scope.col2Tab.push(el);
};
},
link: {
post: function(scope, element, attrs) {
console.info('post-link - dropright');
// Here, I want to move some of the elements of #col1-el
// into #col2-el
}
},
templateUrl: 'dropright-tpl.html'
};
})
.directive('col1Item', function($interpolate) {
return {
require: '^dropright',
restrict: 'E',
transclude: true,
controller: function() {
console.log('-- controller - col1Item');
},
link: {
post: function(scope, element, attrs, droprightCtrl) {
console.log('-- post-link - col1Item');
droprightCtrl.addCol1Item(element.children()[0]);
}
},
templateUrl: 'col1-tpl.html'
};
})
.directive('col2Item', function() {
var directiveDefinitionObject = {
require: '^dropright',
restrict: 'E',
transclude: true,
controller: function() {
console.log('---- controller - col2Item');
},
link: {
post: function(scope, element, attrs, droprightCtrl) {
console.log('---- post-link - col2Item');
droprightCtrl.addCol2Item(element.children()[0]);
}
},
templateUrl: 'col2-tpl.html'
};
return directiveDefinitionObject;
});
Есть ли какой-либо чистый способ выполнения функции ссылки для директивы после всех функций связи ее дочерних элементов при использовании перехода?