77 votes

Elément d'entrée angulaire2 + autofocus

Comment puis-je autofocus élément d'entrée? Semblable à cette question, mais pas avec AngularDart. Quelque chose comme ceci:

<input type="text" [(ngModel)]="title" [focus] />
//or 
<input type="text" [(ngModel)]="title" autofocus />

Ne Angular2 a tout à construire dans le support de cette fonctionnalité?

Mieux fermer question est ce un seul, mais est-il plus court/solution plus facile, puisque je n'ai pas de "liste de champs". Dans le lien fourni *ngFor="#input of inputs" est utilisé, mais j'ai seulement 1 d'entrée dans le modèle de contrôle.

100voto

Makla Points 2796

Voici mon code actuel:

import { Directive, ElementRef, Input } from "@angular/core";

@Directive({
    selector: "[autofocus]"
})
export class AutofocusDirective
{
    private focus = true;

    constructor(private el: ElementRef)
    {
    }

    ngOnInit()
    {
        if (this.focus)
        {
            //Otherwise Angular throws error: Expression has changed after it was checked.
            window.setTimeout(() =>
            {
                this.el.nativeElement.focus(); //For SSR (server side rendering) this is not safe. Use: https://github.com/angular/angular/issues/15008#issuecomment-285141070)
            });
        }
    }

    @Input() set autofocus(condition: boolean)
    {
        this.focus = condition !== false;
    }
}

cas d'utilisation:

[autofocus] //will focus
[autofocus]="true" //will focus
[autofocus]="false" //will not focus

Codes périmés (ancien réponse, juste au cas où):
J'ai fini avec ce code:

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

@Directive({
    selector: '[autofocus]'
})
export class Autofocus
{
    constructor(private el: ElementRef, private renderer: Renderer)
    {        
    }

    ngOnInit()
    {        
    }

    ngAfterViewInit()
    {
        this.renderer.invokeElementMethod(this.el.nativeElement, 'focus', []);
    }
}

Si je mets le code en ngOnViewInit il ne fonctionne pas. Code aussi utiliser les meilleures pratiques, depuis l'appel de se concentrer sur l'élément directement n'est pas recommandé.

Édité (conditionnel autofocus):
Il y A quelques jours j'avais besoin d'conditionnelle auto focus, parce que j'ai cacher d'abord autofocus élément et je veux me concentrer un autre, mais uniquement lors de la première n'est pas visible, et j'ai fini avec ce code:

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

@Directive({
    selector: '[autofocus]'
})
export class AutofocusDirective
{
    private _autofocus;
    constructor(private el: ElementRef, private renderer: Renderer)
    {
    }

    ngOnInit()
    {
    }

    ngAfterViewInit()
    {
        if (this._autofocus || typeof this._autofocus === "undefined")
            this.renderer.invokeElementMethod(this.el.nativeElement, 'focus', []);
    }

    @Input() set autofocus(condition: boolean)
    {
        this._autofocus = condition != false;
    }
}

Edited2:
Moteur de rendu.invokeElementMethod est obsolète et nouvelles Renderer2 ne le supporte pas. Nous sommes donc de retour à la maternelle focus (qui ne travaillent pas à l'extérieur de DOM - SSR, par exemple!).

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

@Directive({
    selector: '[autofocus]'
})
export class AutofocusDirective
{
    private _autofocus;
    constructor(private el: ElementRef)
    {
    }

    ngOnInit()
    {
        if (this._autofocus || typeof this._autofocus === "undefined")
            this.el.nativeElement.focus();      //For SSR (server side rendering) this is not safe. Use: https://github.com/angular/angular/issues/15008#issuecomment-285141070)
    }

    @Input() set autofocus(condition: boolean)
    {
        this._autofocus = condition != false;
    }
}

cas d'utilisation:

[autofocus] //will focus
[autofocus]="true" //will focus
[autofocus]="false" //will not focus

50voto

Hampus Points 106

autofocus est un natif html fonctionnalité qui devrait fonctionner au moins pour la page d'initialisation. Cependant, il ne parvient pas à travailler avec de nombreux angulaire des scénarios, en particulier avec *ngIf.

Vous pouvez faire un vraiment simple et personnalisé directive pour obtenir le comportement souhaité.

import { Directive, OnInit, ElementRef } from '@angular/core';

@Directive({
  selector: '[myAutofocus]'
})
export class AutofocusDirective implements OnInit {

  constructor(private elementRef: ElementRef) { };

  ngOnInit(): void {
    this.elementRef.nativeElement.focus();
  }

}

La directive ci-dessus fonctionne pour mon cas d'utilisation.

Comment utiliser

<input *ngIf="someCondition" myAutofocus />

EDIT: Il semble y avoir usecases où il est trop tôt pour appeler focus dans l' OnInit du cycle de vie de la méthode. Si c'est le cas, le changement d' OnAfterViewInit à la place.

24voto

rinukkusu Points 14217

Vous pouvez affecter à l'élément d'entrée une variable de référence de modèle #myInput :

 <input type="text" [(ngModel)]="title" #myInput />
 

Laissez votre composant implémenter AfterViewInit , saisissez la référence de l'élément d'entrée avec l'annotation ViewChild et focalisez votre élément dans le crochet ngAfterViewInit :

 export class MyComponent implements AfterViewInit {
    @ViewChild("myInput") private _inputElement: ElementRef;

    [...]

    ngAfterViewInit(): void {
        this._inputElement.nativeElement.focus();
    }
}
 

22voto

Michael Lang Points 791

La directive suivante fonctionne pour moi avec Angular 4.0.1

 import {Directive, ElementRef, AfterViewInit} from '@angular/core';

@Directive({
  selector: '[myAutofocus]'
})
export class MyAutofocusDirective implements AfterViewInit {
  constructor(private el: ElementRef)
  {
  }
  ngAfterViewInit()
  {
    this.el.nativeElement.focus();
  }
}
 

utilisez-le comme ceci:

 <md-input-container>
    <input mdInput placeholder="Item Id" formControlName="itemId" name="itemId" myAutofocus>
</md-input-container>
 

L'option d'utiliser l'événement de cycle de vie OnInit ne fonctionnait pas pour moi. J'ai également essayé d'utiliser le moteur de rendu dans l'autre réponse, ce qui n'a pas fonctionné pour moi.

21voto

Sergey Gurin Points 456
 <input type="text" [(ngModel)]="title" #myInput />
{{ myInput.focus() }}
 

ajoutez simplement {{myInput.focus ()}} juste après la saisie dans le modèle

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X