Frage Wie bekomme ich dom-Element in winkel 2 [duplizieren]


Diese Frage hat hier bereits eine Antwort:

Ich habe eine Komponente, die eine hat p Element. Es ist onClick Ereignis wird es zu a ändern textarea So kann der Benutzer die Daten bearbeiten. Meine Frage ist:

  • Wie kann ich den Fokus auf den Textbereich legen?
  • Wie kann ich das Element erreichen, damit ich das .focus () darauf anwenden kann?
  • Kann ich vermeiden, document.getElemenntById () zu verwenden?

Ich habe versucht, die "ElementRef" und die "@ViewChild ()" zu verwenden, aber es scheint, dass ich etwas vermisse:

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


76
2017-08-14 17:25


Ursprung


Antworten:


Benutzen AnsichtChild mit #lokale Variable wie hier gezeigt,

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

</textarea>

In der Komponente,

ÄLTESTER Weg

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

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


Alter Weg

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

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


Aktualisiert am 22/03 (März) / 2017

Neuer Weg

Bitte beachten Sie von Angular v4.0.0-rc.3 (2017-03-10) Wenige Dinge wurden verändert. Da angular Team wird ablehnen invokeElementMethod, über dem Code kann nicht mehr verwendet werden.

Änderungen vornehmen

seit 4.0 rc.1:

Benennen Sie RendererV2 in Renderer2 um
  Benennen Sie RendererTypeV2 in RendererType2 um
  Benennen Sie RendererFactoryV2 in RendererFactory2 um

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) gibt Ihnen folgende Methoden und Sie können jetzt sehen invokeElementMethod ist nicht da. Das Anhängen von img ist noch nicht dokumentiert.

HINWEIS: Sie können folgende Methoden verwenden: Rendere2 mit ohne ViewChild-Variable um so viele Dinge zu tun.

enter image description here


118
2017-08-14 17:46



Update (mit Renderer): 

Beachten Sie, dass der ursprüngliche Renderer-Dienst jetzt nicht mehr unterstützt wird   Bevorzugung von Renderer2

einen Sohn Renderer2 offizielles Dokument

Wie Günter Zöchbauer weiter ausführt:

Eigentlich ist die Verwendung von ElementRef in Ordnung. Auch verwenden   ElementRef.nativeElement mit Renderer2 ist in Ordnung. Was ist entmutigt?   greift direkt auf die Eigenschaften von ElementRef.nativeElement.xxx zu.


Sie können dies erreichen, indem Sie elementRef sowie von ViewChild. es ist jedoch nicht empfehlenswert zu verwenden elementRef durch:

  • Sicherheitsproblem
  • enge Kopplung

wie von offizielle ng2 Dokumentation.

1. Verwenden elementRef (Direkter Zugang):

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

2. Verwenden ViewChild (besserer Ansatz):

<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. Verwenden 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();
      }

    }

40
2017-08-14 17:51



Angular 2.0.0 Finale:

Ich habe festgestellt, dass mit einem ViewChild Setter ist die zuverlässigste Methode zum Festlegen des anfänglichen Formularsteuerungsfokus:

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

Der Setter wird zuerst mit einem aufgerufen undefined Wert gefolgt von einem Aufruf mit einer Initialisierung ElementRef.

Arbeitsbeispiel und vollständige Quelle hier: http://plnkr.co/edit/u0sLLi?p=preview

Verwenden von TypeScript 2.0.3 Final / RTM, Angular 2.0.0 Final / RTM und Chrome 53.0.2785.116 m (64-Bit).

UPDATE für Angular 4+

Renderer wurde zugunsten von abgelehnt Renderer2, aber Renderer2  hat nicht das invokeElementMethod. Sie müssen direkt auf das DOM zugreifen, um den Fokus auf zu setzen input.nativeElement.focus().

Ich finde das immer noch ViewChild Setter Ansatz funktioniert am besten. Beim Benutzen AfterViewInit Ich bekomme manchmal read property 'nativeElement' of undefined Error.

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

11
2017-09-24 17:45