Warum template-lokale Variablen sind nicht verwendbar in templates bei der Verwendung von *ngIf?
Teil 1: "#test" ist nicht definiert, wenn mit *ngIf
Beim verweisen auf einen Eingang, der versteckt werden kann/"zerstört" (weil die *ngIf
verwendet wird, und einige der Elemente zerstört werden), wird die lokale variable erstellt, indem der hashtag syntax #
(#test
im Beispiel unten) funktioniert nicht, auch wenn das element vorhanden ist, in die Seite.
War der code:
@Component({
selector: 'my-app',
template: `<h1>My First Angular 2 App</h1>
<button (click)="focusOther(test)">test</button>
<input #test *ngIf="boolValue" >
`
})
export class AppComponent {
private isVisible = false;
focusOther(testElement){
this.isVisible = true;
alert(testElement);
testElement.focus();
}
}
Die Warnung zeigt undefined
, weil nichts übergeben wird, die Funktion.
Gibt es eine Lösung, damit es funktioniert?
Mein Ziel ist es, den Fokus auf ein element erstellt werden.
Lösung gegeben, die durch Mark Rajcok: stellen eine Richtlinie mit einer afterViewInit verwendet elementRef und Anrufe .focus() auf das element.
Sehen diese plunker für eine funktionierende version von Teil 1:
http://plnkr.co/edit/JmBBHMo1hXLe4jrbpVdv?p=preview
Teil 2, wie neu zu konzentrieren, das element nach der anfänglichen Erstellung
Einmal dieses problem der "focus nach der Schöpfung" ist behoben, ich brauche einen Weg, um re-focus() eine Komponente, wie in "test.focus()" (wobei #test wird die lokale variable name für die Eingabe, nicht aber, wie ich gezeigt, vor).
Mehrere Lösungen gegeben durch Mark Rajcok
- Siehe auch github.com/angular/angular/issues/6179
- Ich füllte das Problem auf Winkel-repo, da es ein bug ist, wenn man die eigentliche Dokumentation, die besagt "Wir können eine lokale template-Variablen auf das gleiche element, auf ein gleichrangiges element oder seine untergeordneten Elemente.".
Du musst angemeldet sein, um einen Kommentar abzugeben.
Als nach einer Lösung für das Fokus-problem haben, könnten Sie ein Attribut Richtlinie
focusMe
:Plunker
Update 1: Hinzufügen der Lösung, die für die re-focus-Funktion:
Plunker
Alternative zur Verwendung
setTimeout()
zurücksetzen, um die Fokus-Eigenschaft auffalse
wäre um ein Ereignis zu erstellen/output-Eigenschaft auf die FocusDirective, undemit()
ein Ereignis, wennfocus()
genannt wird. Die AppComponent würde dann hören, dass Ereignis und setzen Sie die Fokus-Eigenschaft.Update 2: Hier ist eine alternative/bessere Möglichkeit, um die re-focus-Funktion, mit ViewChild. Wir brauchen nicht zu verfolgen, im Fokus Stand diese Weise, noch brauchen wir ein input-Eigenschaft auf die FocusMe Richtlinie.
Plunker
Update 3: Hier ist noch eine alternative, die nicht erforderlich ist eine Richtlinie, die immer noch verwendet ViewChild, aber wir Zugriff auf das Kind über ein lokales template-Variablen eher als ein Attribut-Richtlinie (danke @alexpods für den Tipp):
Plunker
Update 4: ich aktualisierte den code in Update 3 zu verwenden NgZone, so dass wir nicht Ursache Angular change-detection-Algorithmus zu laufen, nachdem die
setTimeout()
beendet. (Für mehr über change detection, siehe diese Antwort).Update 5: ich aktualisierte den code in der oben plunker zu verwenden-Renderer, um es web-worker sicher. Zugriff auf
focus()
direkt aufnativeElement
wird abgeraten.Habe ich eine Menge gelernt von dieser Frage.