Angular2-focalisation d'une zone de texte sur la charge des composants
je développe un composant dans Angular2 (Beta 8). Le composant a une boîte de texte et un dropdown. Je voudrais mettre le focus dans textbox dès que le component est chargé ou lors d'un changement de dropdown. Comment y parvenir en angular2. Ce qui suit est Html pour le composant.
<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>
7 réponses
utilisant l'attribut simple autofocus
HTML5 works for' on load 'scenario
<input autofocus placeholder="enter text" [(ngModel)]="test">
ou
<button autofocus (click)="submit()">Submit</button>
Cette réponse est inspiré par la poste Angulaire 2: Focus sur les nouveaux ajouté l'élément d'entrée
étapes pour mettre l'accent sur L'élément Html dans Angular2
-
importer des enfants-vue dans votre composant
import { Input, Output, AfterContentInit, ContentChild,AfterViewInit, ViewChild, ViewChildren } from 'angular2/core';
-
déclarez le nom de la variable du modèle local pour le html pour lequel vous voulez mettre l'accent
- mettre en œuvre la fonction ngAfterViewInit() ou d'autres crochets appropriés du cycle de vie
-
voici le code que j'ai utilisé pour définir la mise au point
ngAfterViewInit() {vc.first.nativeElement.focus()}
-
ajouter
#input
attribut à L'élément DOM que vous voulez accéder.
///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>
la question initiale demandait une façon de se concentrer d'abord, ou de se concentrer plus tard, en réponse à un événement. Il semble que la bonne façon d'aborder ceci est de créer une directive attribut qui peut être définie pour n'importe quel élément d'entrée, puis d'utiliser un événement personnalisé pour déclencher en toute sécurité la méthode focus sur cet élément d'entrée. Pour ce faire, créer d'abord la directive:
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', []);
});
}
}
notez qu'il utilise un renderer.invokeElementMethod sur le nativeElement, qui est web travailleur en sécurité. Notez également que focusEvent est déclaré comme un input.
ajouter ensuite les déclarations suivantes au composant Angular 2 qui a le modèle où vous souhaitez utiliser la nouvelle directive pour mettre l'accent sur un élément d'entrée:
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);
}
n'oubliez pas d'importer EventEmitter au-dessus du composant comme ceci:
import { Component, EventEmitter } from '@angular/core';
et dans le modèle pour ce composant, définissez le nouvel attribut [focus] comme ceci:
<input id="name" type="text" name="name"
[(ngModel)]="person.Name" class="form-control"
[focus]="focusSettingEventEmitter">
enfin, dans votre module, importez et déclarez la nouvelle directive comme ceci:
import { FocusDirective } from './focus.directive';
@NgModule({
imports: [ BrowserModule, FormsModule ],
declarations: [AppComponent, AnotherComponent, FocusDirective ],
bootstrap: [ AppComponent ]
})
pour récapituler: la fonction ngAfterViewInit fera émettre le nouveau EventEmitter, et puisque nous avons assigné cet émetteur à l'attribut [focus] dans l'élément input de notre modèle, et que nous avons déclaré Ce EventEmitter comme input à la nouvelle directive et invoqué la méthode focus dans la fonction arrow que nous avons passé à l'abonnement à cet événement, l'élément input recevra focus après l'initialisation du composant, et chaque fois que setFocus est appelé.
j'ai eu le même besoin dans ma propre application, et cela a fonctionné comme annoncé. Merci beaucoup à ce qui suit: http://blog.thecodecampus.de/angular-2-set-focus-element /
<input id="name" type="text" #myInput />
{{ myInput.focus() }}
c'est le meilleur et le plus simple moyen, parce que code" myInput.focus()" s'exécute après l'entrée créé
Voir Angulaire 2: Focus sur les nouveaux ajouté l'élément d'entrée pour savoir comment régler le focus.
Pour "à la charge" utiliser le ngAfterViewInit()
cycle de vie de rappel.
j'ai eu un problème légèrement différent. J'ai travaillé avec des entrées dans un modal et ça m'a rendu fou. Aucune des solutions proposées n'a fonctionné pour moi.
Jusqu'à ce que je trouve ce numéro: https://github.com/valor-software/ngx-bootstrap/issues/1597
ce bon gars m'a donné l'indication que ngx-bootstrap modal a une configuration de mise au point. Si cette configuration n'est pas définie à false, le modal sera focalisé après l'animation et il n'y a aucun moyen de focaliser quoi que ce soit d'autre.
mise à jour:
pour définir cette configuration, ajouter l'attribut suivant au div modal:
[config]="{focus: false}"
mise à jour 2:
pour forcer la mise au point sur le champ d'entrée j'ai écrit une directive et mis la mise au point dans chaque cycle vérifié par la suite aussi longtemps que le champ d'entrée a le classe ng-intact.
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', []);
}
}
Je n'ai pas eu beaucoup de chance avec beaucoup de ces solutions sur tous les navigateurs. C'est la solution qui a fonctionné pour moi.
pour les changements de routeur:
router.events.subscribe((val) => {
setTimeout(() => {
if (this.searchElement) {
this.searchElement.nativeElement.focus();
}
}, 1);
})
puis ngAfterViewInit()
pour le scénario onload.