154 votes

Comment obtenir l'élément dom en angle 2

J'ai un composant qui a un p élément. Ses onClick événement va changer à une textarea de sorte que l'utilisateur peut modifier les données. Ma question est:

  • Comment je peux la faire la mise au point sur le textarea?
  • Comment je peux arriver à l'élément afin que je puisse appy l' .focus() sur celui-ci?
  • Puis-je éviter l'utilisation de document.getElemenntById() ?

J'ai essayé d'utiliser le "ElementRef" et le "@ViewChild()" cependant, il semble qu'il me manque quelque chose:

// ------ THE CLASS
@ViewChild('tasknoteId') taskNoteRef:ElementRef;

  noteEditMode: boolean = false;

 get isShowNote (){
    return  !this.noteEditMode && this.todo.note  ? true : false;
  }
  taskNote: string;
  toggleNoteEditMode () {
    this.noteEditMode = !this.noteEditMode;
      this.renderer.invokeElementMethod(this.taskNoteRef.nativeElement,'focus');
  }

// ------ THE COMPONENT
<span class="the-insert">
      <form [hidden]="!noteEditMode && todo.note">
        <textarea #tasknoteId id="tasknote"
                  name="tasknote"
                  [(ngModel)]="todo.note"
                  placeholder="{{ notePlaceholder }}"
                  style="background-color:pink"
                  (blur)="updateNote()" (click)="toggleNoteEditMode()"
                  [autofocus]="noteEditMode"
                  [innerHTML]="todo.note">
        </textarea>
      </form>
     </span>

207voto

micronyks Points 4214

Utilisation ViewChild avec #localvariable comme indiqué ici,

<textarea  #someVar  id="tasknote"
                  name="tasknote"
                  [(ngModel)]="taskNote"
                  placeholder="{{ notePlaceholder }}"
                  style="background-color: pink"
                  (blur)="updateNote() ; noteEditMode = false " (click)="noteEditMode = false"> {{ todo.note }} 

</textarea>

En composant,

Plus ancienne méthode

import {ElementRef} from '@angular/core';
@ViewChild('someVar') el:ElementRef;

ngAfterViewInit()
{
   this.el.nativeElement.focus();
}


ANCIENNE

import {ElementRef} from '@angular/core';
@ViewChild('someVar') el:ElementRef;

constructor(private rd: Renderer) {}
ngAfterViewInit() {
    this.rd.invokeElementMethod(this.el.nativeElement,'focus');
}


Mis à jour le 22/03(Mars)/2017

NOUVELLE Façon

Veuillez noter à partir Angulaire v4.0.0-rc.3 (2017-03-10) , peu de choses ont changé. Depuis Angulaire de l'équipe va déprécier invokeElementMethod, code ci-dessus ne peuvent plus être utilisés.

DERNIÈRES MODIFICATIONS

depuis 4.0 rc.1:

renommer RendererV2 à Renderer2
renommer RendererTypeV2 à RendererType2
renommer RendererFactoryV2 à RendererFactory2

import {ElementRef,Renderer2} from '@angular/core';
@ViewChild('someVar') el:ElementRef;

constructor(private rd: Renderer2) {}

ngAfterViewInit() {
      console.log(this.rd); 
      this.el.nativeElement.focus();      //<<<=====same as oldest way
}

console.log(this.rd) vous donnera une des méthodes suivantes et vous pouvez le voir maintenant, invokeElementMethod n'est pas là. Fixation img encore il n'est pas documentée.

REMARQUE: Vous pouvez utiliser les méthodes suivantes de l' Rendere2 avec/sans ViewChild variable à faire beaucoup de choses.

enter image description here

92voto

candidJ Points 2751

Mise à jour (à l'aide de moteur de rendu):

Notez qu'à l'origine le moteur de Rendu service a été abandonné dans faveur de Renderer2

comme sur Renderer2 officiel doc.

En outre, comme l'a souligné @GünterZöchbauer:

En fait l'utilisation de ElementRef est tout simplement parfait. Aussi à l'aide de ElementRef.nativeElement avec Renderer2 est très bien. Ce qui est découragé est accéder à des propriétés de ElementRef.nativeElement.xxx directement.


Vous pouvez atteindre cet objectif en utilisant elementRef ainsi que par ViewChild. cependant, il n'est pas recommandé d'utiliser elementRef en raison de:

  • problème de sécurité
  • le couplage

comme l'a souligné officiel ng2 de la documentation.

1. À L'Aide De elementRef (Accès Direct):

export class MyComponent {    
constructor (private _elementRef : elementRef) {
 this._elementRef.nativeElement.querySelector('textarea').focus();
 }
}

2. À l'aide de ViewChild (meilleure approche):

<textarea  #tasknote name="tasknote" [(ngModel)]="taskNote" placeholder="{{ notePlaceholder }}" 
style="background-color: pink" (blur)="updateNote() ; noteEditMode = false " (click)="noteEditMode = false"> {{ todo.note }} </textarea> // <-- changes id to local var


export class MyComponent implements AfterViewInit {
  @ViewChild('tasknote') input: ElementRef;

   ngAfterViewInit() {
    this.input.nativeElement.focus();

  }
}

3. À l'aide de renderer:

export class MyComponent implements AfterViewInit {
      @ViewChild('tasknote') input: ElementRef;
         constructor(private renderer: Renderer2){           
          }

       ngAfterViewInit() {
       //using selectRootElement instead of depreaced invokeElementMethod
       this.renderer.selectRootElement(this.input["nativeElement"]).focus();
      }

    }

11voto

KTCO Points 1123

Angulaire 2.0.0 Finale:

J'ai trouvé que l'utilisation d'un ViewChild setter est la plus fiable pour définir la forme initiale de contrôle de l'accent:

@ViewChild("myInput")
set myInput(_input: ElementRef | undefined) {
    if (_input !== undefined) {
        setTimeout(() => {
            this._renderer.invokeElementMethod(_input.nativeElement, "focus");
        }, 0);
    }
}

Le setter est d'abord appelée avec un undefined de la valeur suivie d'un appel avec un initialisé ElementRef.

Exemple de travail et source complet ici: http://plnkr.co/edit/u0sLLi?p=preview

À l'aide de la Machine 2.0.3 Final/RTM, Angulaire 2.0.0 Final/RTM, et Chrome 53.0.2785.116 m (64-bit).

Mise à JOUR Angulaire 4+

Renderer a été dépréciée en faveur de l' Renderer2, mais Renderer2 n'ont pas l' invokeElementMethod. Vous aurez besoin pour accéder au DOM directement pour définir le focus comme en input.nativeElement.focus().

Je suis toujours à trouver que le ViewChild setter approche qui fonctionne le mieux. Lors de l'utilisation d' AfterViewInit parfois, j'ai des read property 'nativeElement' of undefined d'erreur.

@ViewChild("myInput")
set myInput(_input: ElementRef | undefined) {
    if (_input !== undefined) {
        setTimeout(() => { //This setTimeout call may not be necessary anymore.
            _input.nativeElement.focus();
        }, 0);
    }
}

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