Pertanyaan Cara mendapatkan elemen dom di sudut 2 [duplikat]


Pertanyaan ini sudah memiliki jawaban di sini:

Saya memiliki komponen yang memiliki p elemen. Nya onClick acara akan mengubahnya menjadi a textarea sehingga pengguna dapat mengedit data. Pertanyaanku adalah:

  • Bagaimana saya bisa membuat fokus pada textarea?
  • Bagaimana saya bisa mencapai elemen sehingga saya bisa appy. Fokus () di atasnya?
  • Bisakah saya menghindari menggunakan document.getElemenntById ()?

Saya telah mencoba menggunakan "ElementRef" dan "@ViewChild ()" namun sepertinya saya kehilangan sesuatu:

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


asal


Jawaban:


Menggunakan LihatChild dengan #localvariable seperti yang ditunjukkan di sini,

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

</textarea>

Dalam komponen,

Cara yang paling tua

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

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


Jalan LAMA

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

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


Diperbarui pada 22/03 (Maret) / 2017

Jalan baru

Harap dicatat dari Angular v4.0.0-rc.3 (2017-03-10) beberapa hal telah berubah. Karena tim Angular akan mencela invokeElementMethod, kode di atas tidak lagi dapat digunakan.

MENGUBAH PERUBAHAN

sejak 4.0 rc.1:

ganti nama RendererV2 menjadi Renderer2
  ganti nama RendererTypeV2 menjadi RendererType2
  ganti nama RendererFactoryV2 menjadi 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) akan memberi Anda metode berikut dan Anda dapat melihat sekarang invokeElementMethod tidak di sana. Melampirkan img belum didokumentasikan.

CATATAN: Anda dapat menggunakan metode berikut Rendere2 dengan tanpa Variabel ViewChild untuk melakukan banyak hal.

enter image description here


118
2017-08-14 17:46



Pembaruan (menggunakan perender): 

Perhatikan bahwa layanan Renderer asli sekarang sudah tidak digunakan lagi   mendukung Renderer2

seorang anak Dok resmi Renderer2.

Selanjutnya, seperti yang ditunjukkan oleh @ GünterZöchbauer:

Sebenarnya menggunakan ElementRef baik-baik saja. Juga menggunakan   ElementRef.nativeElement dengan Renderer2 baik-baik saja. Apa yang putus asa   adalah mengakses properti ElementRef.nativeElement.xxx secara langsung.


Anda dapat mencapai ini dengan menggunakan elementRef begitu juga dengan ViewChild. namun tidak disarankan untuk digunakan elementRef disebabkan oleh:

  • masalah keamanan
  • kopling yang ketat

seperti yang ditunjukkan oleh dokumentasi ng2 resmi.

1. Menggunakan elementRef (Akses langsung):

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

2. Menggunakan ViewChild (pendekatan yang lebih baik):

<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. Menggunakan 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 Final:

Saya telah menemukan bahwa menggunakan ViewChild setter adalah cara yang paling andal untuk menetapkan fokus kontrol bentuk awal:

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

Setter pertama kali dipanggil dengan undefined nilai diikuti oleh panggilan dengan diinisialisasi ElementRef.

Contoh kerja dan sumber lengkap di sini: http://plnkr.co/edit/u0sLLi?p=preview

Menggunakan TypeScript 2.0.3 Final / RTM, Angular 2.0.0 Final / RTM, dan Chrome 53.0.2785.116 m (64-bit).

UPDATE untuk Angular 4+

Renderer tidak lagi mendukung Renderer2, tapi Renderer2  tidak memiliki itu invokeElementMethod. Anda harus mengakses DOM secara langsung untuk mengatur fokus seperti pada input.nativeElement.focus().

Saya masih menemukan bahwa ViewChild setter pendekatan bekerja paling baik. Ketika menggunakan AfterViewInit Saya terkadang mendapatkannya read property 'nativeElement' of undefined kesalahan.

@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