Как запросить вложенный элемент DOM директивы Angularjs с помощью динамического селектора?
Распределение директив внутри родительского шаблона:
<div badge></div>
Директивный шаблон templates/badge.html
:
Обратите внимание на распределение динамического идентификатора, используя директиву $id
,
<div>
<span id="id{{ ::$id }}_name">Nik Sumeiko, Frontend engineer</span>
</div>
Директива:
angular.module('app').directive('badge', () => ({
restrict: "A",
replace: true,
templateUrl: "templates/badge.html",
link: (scope, element, attributes) => {
// Tries to query nested DOM element by a dynamic selector.
const name = element.find(`#id${scope.$id}_name`);
console.log(name.length, element.html());
}
}));
По выводу консоли ясно видно, что шаблон директивы еще не скомпилировал свои динамические значения:
0 "
<div>
<span id="id{{ ::$id }}_name">Nik Sumeiko, Frontend engineer</span>
</div>
"
Как тогда можно запросить вложенные элементы динамическим селектором? Существуют ли другие методы директив, которые отправляются после рендеринга угловых динамических значений шаблона?
Пожалуйста, не предлагайте использовать $timeout
встроенная функция для задержки рендеринга шаблона внутри link
метод, так как я не думаю, что это правильный путь...
1 ответ
Вот цитата из угловой документации:
После связывания представление не обновляется до тех пор, пока не будет вызван вызов $digest, который обычно выполняется Angular автоматически.
Вот почему вы не можете найти элементы, содержащие выражения в их идентификаторе - в это время представление не обновляется.
Вот обходные пути:
Создайте элемент и присоедините его к DOM вручную
Таким образом, у вас есть ссылка на элемент, поэтому вам не нужно запрашивать его:
link: (scope, element, attributes) => {
let span = $compile('<span id="id{{ ::$id }}_name">Nik Sumeiko, Frontend engineer</span>')(scope);
// do something to span ...
element.append(span);
}
Используйте $ timeout
Ты можешь использовать $timeout
с нулевой задержкой, это не неправильный путь. $timeout
выполнит ваш код сразу после текущего $digest
цикл, то есть после обновления привязок вида:
link: (scope, element, attributes) => {
$timeout(function() {
let span = element[0].querySelector(`#id${scope.$id}_name`);
});
}