typescript - Angular: få nytt DOM-element från ngFor-loop i komponent
Jag har inte kunnat åstadkomma en sak som bör vara ganska lätt i teorin, och det retar mig verkligen.
Så i princip har jag en tjänst som tillhandahåller viss data för en array, låt oss förenkla det till att vara bara en array av strängar:
public myList: string[] = ['lorem', 'ipsum'];
I min mall skapar jag listobjekt för varje post i arrayen och tilldelar ID:n:
<ul id="listGroup">
<li ngFor="let item of myList" [attr.id]="'item-'+item">{{ item }}</li>
</ul>
Nu har jag några ytterligare funktioner, som utökar listan och lägger till nya objekt. Vad jag i princip skulle vilja göra härnäst är att få tillgång till varje nytt DOM-element som skapas som ett resultat av att nya objekt läggs till i listan.
Jag har försökt med detta genom att använda ElementRef och querySelector-metoden för nativeElement. Låt oss säga att jag redan prenumererat på något i min komponent, vilket meddelar mig om nyss tillagda objekt i min array och det ger också motsvarande värde, så att jag kan sammanställa rätt element-ID:
this.elementRef.nativeElement.querySelector('#item-'+item);
Sammantaget sätter jag detta i en ngAfterViewInit()-livscykel-hook och skulle anta att jag skulle hitta varje nyss tillagd DOM-element. Men nej! Jag får alltid bara tillbaka "undefined". Så det verkar som att DOM-elementet ännu inte är tillgängligt, hur skulle jag på rätt sätt "vänta" på att elementet ska finnas där och vara åtkomligt för min komponent?
Jag hoppas att detta gör det tillräckligt klart vad mitt problem är, om inte kanske jag behöver lägga till lite mer kod, vilket är lite svårt på mobilen dock.
Tack för all hjälp!
Andy
Svar #1
Här är ett exempel på hur du kan få elementreferenser. Du kan anpassa det till ditt fall:
Typescript-direktiv
.....
@Input('focusOnInit') priority: number = 0;
static instances: FocusOnInitDirective[] = [];
constructor(public renderer: Renderer, public elementRef: ElementRef) {
}
ngOnInit(): void {
FocusOnInitDirective.instances.push(this)
}
ngAfterViewInit(): void {
setTimeout(() => {
FocusOnInitDirective.instances.splice(FocusOnInitDirective.instances.indexOf(this), 1);
});
if (FocusOnInitDirective.instances.every((i) => this.priority >= i.priority)) {
this.renderer.invokeElementMethod(
this.elementRef.nativeElement, 'focus', []);
}
}
}
HTML
<button type="button" (click)=add()>Add</button>
<div *ngFor="let input of inputs">
<input type="text" focusOnInit="3">
<input type="text" focusOnInit="2">
<input type="text" focusOnInit="1">
</div>
Komponent typescript:
....
inputs = [];
add() {
this.inputs.push(this.inputs.length+1);
}
Och plunkaren
