wake-up-neo.com

Angular2 - Fokussierung eines Textfelds auf das Laden von Komponenten

Ich entwickle eine Komponente in Angular2 (Beta 8). Die Komponente verfügt über ein Textfeld und eine Dropdown-Liste. Ich möchte den Fokus in der Textbox einstellen, sobald eine Komponente geladen wird oder bei einem Dropdown-Ereignis. Wie würde ich das in Angle2 erreichen? Folgendes ist HTML für die Komponente. 

<div>
    <form role="form" class="form-horizontal ">        
        <div [ngClass]="{showElement:IsEditMode, hidden:!IsEditMode}">
            <div class="form-group">
                <label class="control-label col-md-1 col-sm-1" for="name">Name</label>
                <div class="col-md-7 col-sm-7">
                    <input id="name" type="text" [(ngModel)]="person.Name" class="form-control" />

                </div>
                <div class="col-md-2 col-sm-2">
                    <input type="button" value="Add" (click)="AddPerson()" class="btn btn-primary" />
                </div>
            </div>
        </div>
        <div [ngClass]="{showElement:!IsEditMode, hidden:IsEditMode}">
            <div class="form-group">
                <label class="control-label col-md-1 col-sm-1" for="name">Person</label>
                <div class="col-md-7 col-sm-7">
                    <select [(ngModel)]="SelectedPerson.Id"  (change)="PersonSelected($event.target.value)" class="form-control">
                        <option *ngFor="#item of PeopleList" value="{{item.Id}}">{{item.Name}}</option>
                    </select>
                </div>
            </div>
        </div>        
    </form>
</div>

61
parag

Diese Antwort ist inspiriert von post Angular 2: Fokus auf neu hinzugefügtem Eingabeelement

Schritte, um den Fokus auf das HTML-Element in Angular2 zu setzen

  1. Importieren Sie ViewChildren in Ihre Komponente

    import { Input, Output, AfterContentInit, ContentChild,AfterViewInit, ViewChild, ViewChildren } from 'angular2/core';
    
  2. Deklarieren Sie den Namen der lokalen Vorlagenvariablen für die HTML-Datei, für die Sie den Fokus festlegen möchten

  3. Implementieren Sie die Funktion ngAfterViewInit () oder andere geeignete Lebenszyklus-Hooks
  4. Es folgt der Code, mit dem ich den Fokus eingestellt habe

    ngAfterViewInit() {vc.first.nativeElement.focus()}
    
  5. Fügen Sie das #input-Attribut zu dem DOM-Element hinzu, auf das Sie zugreifen möchten.

///This is TypeScript
import {Component, Input, Output, AfterContentInit, ContentChild,
  AfterViewChecked, AfterViewInit, ViewChild,ViewChildren} from 'angular2/core';

export class AppComponent implements AfterViewInit,AfterViewChecked { 
   @ViewChildren('input') vc;
  
   ngAfterViewInit() {            
        this.vc.first.nativeElement.focus();
    }
  
 }
<div>
    <form role="form" class="form-horizontal ">        
        <div [ngClass]="{showElement:IsEditMode, hidden:!IsEditMode}">
            <div class="form-group">
                <label class="control-label col-md-1 col-sm-1" for="name">Name</label>
                <div class="col-md-7 col-sm-7">
                    <input #input id="name" type="text" [(ngModel)]="person.Name" class="form-control" />

                </div>
                <div class="col-md-2 col-sm-2">
                    <input type="button" value="Add" (click)="AddPerson()" class="btn btn-primary" />
                </div>
            </div>
        </div>
        <div [ngClass]="{showElement:!IsEditMode, hidden:IsEditMode}">
            <div class="form-group">
                <label class="control-label col-md-1 col-sm-1" for="name">Person</label>
                <div class="col-md-7 col-sm-7">
                    <select [(ngModel)]="SelectedPerson.Id"  (change)="PersonSelected($event.target.value)" class="form-control">
                        <option *ngFor="#item of PeopleList" value="{{item.Id}}">{{item.Name}}</option>
                    </select>
                </div>
            </div>
        </div>        
    </form>
</div>

57
parag

Die Verwendung des einfachen autofocus HTML5-Attributs funktioniert für das Szenario "beim Laden"

 <input autofocus placeholder="enter text" [(ngModel)]="test">

oder 

<button autofocus (click)="submit()">Submit</button>

http://www.w3schools.com/TAgs/att_input_autofocus.asp

59
Nikhil Nambiar

In der ursprünglichen Frage wurde nach einer Möglichkeit gefragt, den Fokus anfangs einzustellen, OR, um den Fokus später als Reaktion auf ein Ereignis einzustellen. Es scheint, als wäre dies der richtige Weg, um eine Attributanweisung zu erstellen, die für jedes Eingabeelement festgelegt werden kann, und dann ein benutzerdefiniertes Ereignis zu verwenden, um die Fokusmethode für dieses Eingabeelement sicher auszulösen. Dazu erstellen Sie zunächst die Direktive:

import { Directive, Input, EventEmitter, ElementRef, Renderer, Inject } from '@angular/core';

@Directive({
    selector: '[focus]'
})
export class FocusDirective {
    @Input('focus') focusEvent: EventEmitter<boolean>;

    constructor(@Inject(ElementRef) private element: ElementRef, private renderer: Renderer) {
    }

    ngOnInit() {
        this.focusEvent.subscribe(event => {
            this.renderer.invokeElementMethod(this.element.nativeElement, 'focus', []);
        });
    }
}

Beachten Sie, dass renderer.invokeElementMethod für das nativeElement verwendet wird, was Web-Worker-Safe ist. Beachten Sie auch, dass focusEvent als Eingabe deklariert wird. 

Fügen Sie dann der Angular 2-Komponente, die die Vorlage enthält, in der Sie die neue Direktive verwenden möchten, die folgenden Deklarationen hinzu, um den Fokus auf ein Eingabeelement zu setzen:

public focusSettingEventEmitter = new EventEmitter<boolean>();

ngAfterViewInit() { // ngOnInit is NOT the right lifecycle event for this.
    this.focusSettingEventEmitter.emit(true);
}
setFocus(): void {
  this.focusSettingEventEmitter.emit(true);
}

Vergessen Sie nicht, EventEmitter wie folgt über der Komponente zu importieren:

import { Component, EventEmitter } from '@angular/core';

und legen Sie in der Vorlage für diese Komponente das neue Attribut [focus] wie folgt fest:

<input id="name" type="text" name="name" 
    [(ngModel)]="person.Name" class="form-control"
    [focus]="focusSettingEventEmitter">

Schließlich importieren und deklarieren Sie die neue Direktive in Ihrem Modul folgendermaßen:

import { FocusDirective } from './focus.directive';

@NgModule({
    imports: [ BrowserModule, FormsModule ],
    declarations: [AppComponent, AnotherComponent, FocusDirective ],
    bootstrap: [ AppComponent ]
})

Um es zusammenzufassen: Die Funktion ngAfterViewInit bewirkt, dass der neue EventEmitter emittiert wird. Da wir diesen Emitter dem Attribut [focus] im Eingabeelement in unserer Vorlage zugewiesen haben, haben wir diesen EventEmitter als Eingabe für die neue Direktive deklariert und den Fokus aufgerufen Wenn die Methode in der Pfeilfunktion an das Abonnement dieses Ereignisses übergeben wird, erhält das Eingabeelement den Fokus, nachdem die Komponente initialisiert wurde und wann setFocus aufgerufen wird.

Ich hatte das gleiche Bedürfnis in meiner eigenen App und dies funktionierte wie angekündigt. Vielen Dank an Folgendes: http://blog.thecodecampus.de/angular-2-set-focus-element/

23
Kent Weigel
<input id="name" type="text" #myInput />
{{ myInput.focus() }}

dies ist der beste und einfachste Weg, da code "myInput.focus ()" nach der Eingabe ausgeführt wird

17
Sergey Gurin

Siehe Winkel 2: Fokus auf neu hinzugefügtem Eingabeelement , um den Fokus einzustellen.

Verwenden Sie für "on load" den Lebenszyklus-Callback ngAfterViewInit().

4

Ich hatte ein etwas anderes Problem. Ich arbeitete mit Eingaben in einem modal und es hat mich wahnsinnig gemacht. Keine der vorgeschlagenen Lösungen funktionierte für mich.

Bis ich dieses Problem gefunden habe: https://github.com/valor-software/ngx-bootstrap/issues/1597

Dieser gute Typ gab mir den Hinweis, dass ngx-bootstrap modal eine Fokuskonfiguration hat. Wenn diese Konfiguration nicht auf "false" gesetzt ist, wird der Modal nach der Animation fokussiert und es gibt keine Möglichkeit, alles andere zu fokussieren.

Update:

Um diese Konfiguration festzulegen, fügen Sie dem modalen div das folgende Attribut hinzu: 

[config]="{focus: false}"

Update 2:

Um den Fokus auf das Eingabefeld zu erzwingen, habe ich eine Direktive geschrieben und den Fokus in jedem AfterViewChecked-Zyklus festgelegt, solange das Eingabefeld die Klasse ng-unberührt hat.

 ngAfterViewChecked() {
    // This dirty hack is needed to force focus on an input element of a modal.
    if (this.el.nativeElement.classList.contains('ng-untouched')) {
        this.renderer.invokeElementMethod(this.el.nativeElement, 'focus', []);
    }
}
2
FireGnome

Es kann auch dynamisch so gemacht werden ...

<input [id]="input.id" [type]="input.type" [autofocus]="input.autofocus" />

Wo Eingabe ist

const input = {
  id: "my-input",
  type: "text",
  autofocus: true
};
0
SoEzPz

Ich hatte mit vielen dieser Lösungen in allen Browsern nicht viel Glück. Dies ist die Lösung, die für mich funktioniert hat.

Für Routeränderungen:

router.events.subscribe((val) => {
    setTimeout(() => {
        if (this.searchElement) {
            this.searchElement.nativeElement.focus();
        }
    }, 1);
})

Dann ngAfterViewInit() für das Onload-Szenario.

0
rtaft