Является ли $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');
    }
}
Другие вопросы по тегам