Является ли $timeout лучшей практикой для ожидания в шаблоне директивы Angular?
Шаблон проектирования нашей команды для ожидания отображения шаблона директивы состоит в том, чтобы обернуть наш код манипуляции DOM в $timeout
(внутри функции ссылки директивы), который я когда-то знал, был нормальным шаблоном проектирования. Это все еще правда, или есть более лучшие / безопасные шаблоны проектирования, чтобы сделать это?
Пример шаблона в ECMAScript6:
link: ($scope, $element) => {
$timeout(() => {
var domElementFromTemplate = $element.find('myDOMElement');
}
}
1 ответ
Пока вы пытаетесь выбрать элемент, который доступен в DOM:
Это никогда не было лучшей практикой IMO, потому что нет необходимости создавать асинхронное поведение для синхронной функции dom select. Из-за документации angular.element это должно выглядеть так:
link: ($scope, $element) => {
var domElementFromTemplate = $element.find('myDOMElement');
}
Пока вы пытаетесь выбрать элемент, который должен отображаться в вашей директиве:
Функция тайм-аута должна избегать асинхронного поведения при DOM-рендеринге, но в IMO есть гораздо более подходящие способы решения этой проблемы:
Решение 1)
Другой подход - получить состояние готовности документа, чтобы убедиться, что ваш элемент доступен в DOM, например:
link: ($scope, $element) => {
angular.element(document).ready(() => {
var domElementFromTemplate = $element.find('myDOMElement');
});
}
Решение 2)
Другой подход заключается в создании другой директивы для тех элементов, которые были отображены внутри директивы, например (myDOMElement
) чтобы вообще избежать инъекций DOM.
link: ($scope, $element) => {},
template: "<div some-other-child-directive></div>"
Решение 3)
Должен быть намного лучший и более аккуратный подход к созданию функции обратного вызова, чтобы гарантировать, что элемент доступен в DOM. Это может быть сделано ng-init="someCallback()"
чтобы начать функциональность вашего элемента.
Решение 4)
Да, используя $timeout
по-прежнему работает нормально, а новый $timeout
будет добавлен в очередь выполнения и будет выполнен после рендеринга DOM. Значение задержки не требуется.
link: ($scope, $element) => {
$timeout(() => {
var domElementFromTemplate = $element.find('myDOMElement');
}
}