javascript - Är $timeout fortfarande bästa praxis för att vänta på Angular-direktivets mall?
Vårt teams designmönster för att vänta på att en direktivs mall ska renderas är att omsluta vår DOM-manipulationskod i en $timeout (inuti direktivets länkfunktion), vilket jag vet vid en tidpunkt var det normala designmönstret. Är det fortfarande sant, eller finns det bättre/säkrare designmönster för att göra detta?
Exempel på mönster finns i ECMAScript6:
link: ($scope, $element) => {
$timeout(() => {
var domElementFromTemplate = $element.find('myDOMElement');
}
}
Svar #1
Medan du försöker välja ett element som finns i DOM:
Det har aldrig varit en bästa praxis enligt min åsikt eftersom det inte finns något behov av att skapa ett asynkront beteende för en synkron DOM-urvals-funktion. Enligt angular.element-dokumentationen bör det se ut så här:
link: ($scope, $element) => {
var domElementFromTemplate = $element.find('myDOMElement');
}
Medan du försöker välja ett element som ska renderas i din direktiv:
Timeout-funktionen bör undvika DOM-renderad asynkron beteende, men enligt min åsikt finns det många bättre tillvägagångssätt för att hantera detta problem:
Lösning 1)
Ett annat tillvägagångssätt är att få dokumentets färdiga tillstånd för att säkerställa att ditt element är tillgängligt i DOM, som:
link: ($scope, $element) => {
angular.element(document).ready(() => {
var domElementFromTemplate = $element.find('myDOMElement');
});
}
Lösning 2)
Ett annat tillvägagångssätt är att skapa en annan direktiv för de element som renderades inuti en direktiv, t.ex. (myDOMElement) för att helt undvika DOM-injektion.
link: ($scope, $element) => {},
template: "<div some-other-child-directive></div>"
Lösning 3)
Det borde vara ett mycket bättre och mer ordnat tillvägagångssätt att skapa en callback-funktion för att säkerställa att elementet är tillgängligt i DOM. Detta kan göras med ng-init="someCallback()" för att starta dina elementfunktioner.
Lösning 4)
Ja, att använda $timeout fungerar fortfarande fint medan en ny $timeout kommer att läggas till i exekveringskön och kommer att köras efter att DOM har renderats. Ett timeout-fördröjningsvärde behövs inte.
link: ($scope, $element) => {
$timeout(() => {
var domElementFromTemplate = $element.find('myDOMElement');
}
}
