2016-03-04 12 views
32

Rozwijam komponent w Angular2 (Beta 8). Komponent ma pole tekstowe i rozwijane menu. Chciałbym ustawić fokus w polu tekstowym zaraz po wczytaniu komponentu lub w przypadku zmiany listy rozwijanej. Jak to osiągnąć w kątowym 2. Poniżej znajduje się Html dla komponentu.Angular2 - Ustawianie ostrości w polu tekstowym

<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>

Odpowiedz

33

Ta odpowiedź jest inspirowana przez Pocztę Angular 2: Focus on newly added input element

kroki, aby ustawić ostrość na elemencie html w Angular2

  1. importu ViewChildren w komponencie

    import { Input, Output, AfterContentInit, ContentChild,AfterViewInit, ViewChild, ViewChildren } from 'angular2/core'; 
    
  2. stwierdzenie lokalnego szablonu nazwę zmiennej dla html, dla którego chcesz ustawić ostrość

  3. Wdrożenie ngAfterViewInit function() lub inne odpowiednie haki cyklu życia
  4. Poniżej znajduje się fragment kodu, które służy do ustawiania ostrości

    ngAfterViewInit() {vc.first.nativeElement.focus()} 
    
  5. Dodaj #input atrybutu elementu DOM chcesz dostępem .

///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>

+2

Wystarczająco proste, ale co się stanie, jeśli musisz ustawić fokus w innym komponencie?Na przykład domyślne pole wyszukiwania (w nagłówku) ze składnika podrzędnego. –

+1

A co z dynamicznie generowanym elementem? –

4

Zobacz Angular 2: Focus on newly added input element jak ustawić ostrość.

Dla "przy obciążeniu" należy użyć wywołania zwrotnego cyklu życia ngAfterViewInit().

+0

Wielkie dzięki. Link, który udostępniłeś, był bardzo pomocny. +1 za to. Podzielę się odpowiedzią na ten konkretny scenariusz. – parag

15

Oryginalny pytanie zadane za sposób, aby ustawić ostrość na początku, lub ustawić skupić się później, w odpowiedzi na zdarzenie. Wydaje się, że właściwym sposobem podejścia jest stworzenie dyrektywy atrybutów, która może być ustawiona dla dowolnego elementu wejściowego, a następnie użycie niestandardowego zdarzenia, aby bezpiecznie uruchomić metodę fokusowania na tym elemencie wejściowym. Aby się tak, najpierw utworzyć dyrektywy:

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', []); 
     }); 
    } 
} 

Wykorzystuje to renderer.invokeElementMethod na nativeElement, który jest bezpieczny WWW pracownika. Zauważ również, że focusEvent jest zadeklarowane jako dane wejściowe.

Następnie dodać następujące deklaracje kątowej 2 komponentu, który ma szablonu, w którym chcesz korzystać z nowej dyrektywy, aby ustawić ostrość do elementu wejściowego:

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); 
} 

Nie zapomnij importować EventEmitter powyżej komponent tak:

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

i w szablonie dla tego komponentu, należy ustawić nowy [Ostrość] atrybut tak:

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

Wreszcie w module, importu i zadeklarować nową dyrektywę tak:

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

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

Podsumowując: funkcja ngAfterViewInit spowoduje nowy EventEmitter emitować, a ponieważ przydzielony ten nadajnik do [Ostrość] atrybut w elemencie input w naszym szablonie i zadeklarowaliśmy to EventEmitter jako dane wejściowe do nowej dyrektywy i wywołaliśmy metodę fokusu w funkcji strzałki, którą przekazaliśmy subskrypcji tego zdarzenia, element wejściowy otrzyma fokus po komponencie zainicjalizowany i zawsze, gdy wywoływany jest setFocus.

Miałem tę samą potrzebę w mojej własnej aplikacji i działało jak w reklamie. Dziękuję bardzo do następujących: http://blog.thecodecampus.de/angular-2-set-focus-element/

+0

To jest świetne i działa, ale zastanawiam się, czy to tylko odrobina za dużo pracy dla mniejszego skupienia. Miałem zamiar zrobić to jako fajną rzecz dla użytkownika, ponieważ nie jest to wymagane, ale wydaje się, że nadmierna ilość kodu do zapisania użytkownika jednym kliknięciem. –

34

Korzystanie prosty atrybut autofocus HTML5 pracuje dla 'obciążenia' scenariusza

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

lub

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

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

+13

Wydaje się to działać, jeśli odświeżysz stronę lub załadujesz stronę od podstaw. Jeśli przejdziesz do komponentu formularza za pośrednictwem routera, pole nie zostanie wybrane. –

+4

to jest idealne. Po co zabijać muchy z armaty? : D –

+0

to nie jest dobre rozwiązanie, gdy mamy wiele komponentów, to będzie działać tylko dla pierwszego domyślnego komponentu –

2

miałem nieco inny problem. Pracowałem z wejściami w trybie modalnym i doprowadzało mnie to do szaleństwa. Żadne z zaproponowanych rozwiązań nie zadziałało.

aż znalazłem ten problem: https://github.com/valor-software/ngx-bootstrap/issues/1597

To dobry facet dał mi wskazówkę, że NGX-bootstrap modalnej ma konfigurację ostrości. Jeśli ta konfiguracja nie jest ustawiona na false, modalny zostanie skupiony po animacji i nie ma ŻADNEGO sposobu na skupienie czegokolwiek innego.

Aktualizacja:

Aby ustawić tę konfigurację, należy dodać następujący atrybut do div modalnej:

[config]="{focus: false}" 

Aktualizacja 2:

Aby wymusić ostrość na polu wprowadzania Napisałem dyrektywę i ustawiłem fokus w każdym cyklu AfterViewChecked, o ile pole wejściowe ma klasę ng-untouched.

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', []); 
    } 
} 
+0

Hi @ FireGnome, czy mógłbyś udostępnić gdzie to skonfigurować? – cyberabis

+0

jak widać tutaj: http://valor-software.com/ngx-bootstrap/#/modals#static nie jest atrybutem konfiguracja [config] = "{tła: 'statyczne'}" You można ustawić tam fokus właściwości: false – FireGnome

+0

Witam, mam ten sam problem, dodałem mod i konfigurację ngx i próbowałem dodać fokus za pomocą dyrektywy (bez powodzenia), co użyłeś, aby dodać skupienie do wprowadzić za każdym razem? Dzięki – Simon

Powiązane problemy