การแทนที่ document.getElementById ใน angular4 / typescript?


94

ดังนั้นฉันกำลังทำงานกับ angular4 ในงานฝึกหัดของฉันและนี่เป็นเรื่องใหม่สำหรับฉัน โชคดีเพื่อที่จะได้รับองค์ประกอบ html และค่าที่ฉันใช้ <HTMLInputElement> document.getElementByIdหรือ <HTMLSelectElement> document.getElementById

ฉันสงสัยว่ามีการแทนที่สิ่งนี้ในเชิงมุมหรือไม่


2
ทำไมไม่ใช้ getElementById?
สุเร

แค่สงสัยว่ามันมีวิธีเชิงมุมในการรับองค์ประกอบ
Nino Gutierrez

คำตอบ:


149

คุณสามารถแท็กองค์ประกอบ DOM ของคุณโดยใช้แล้วได้รับมันด้วย#someTag@ViewChild('someTag')

ดูตัวอย่างที่สมบูรณ์:

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

@Component({
    selector: 'app',
    template: `
        <div #myDiv>Some text</div>
    `,
})
export class AppComponent implements AfterViewInit {
    @ViewChild('myDiv') myDiv: ElementRef;

    ngAfterViewInit() {
        console.log(this.myDiv.nativeElement.innerHTML);
    }
}

console.logจะพิมพ์ข้อความบางส่วน


ข้อผิดพลาดแสดงข้อผิดพลาด: ไม่สามารถแก้ไขข้อผิดพลาด '@ angular / core / src / metadata / di': ไม่สามารถแก้ไข '@ angular / core / src / linker / element_ref'
Nino Gutierrez

2
nvm แก้ไขโดยการนำเข้าเช่นนี้ นำเข้า {Component, OnInit, ViewChild, ElementRef} จาก "@ angular / core";
Nino Gutierrez

20
มันจะไม่ทำงานถ้าคุณมีองค์ประกอบ Dom ตามเงื่อนไขเช่น * ngFor, * ngIf ฯลฯ
Ravindra Thorat

Angular 8+ ต้องการสองอาร์กิวเมนต์สำหรับมัณฑนากรของ ViewChild

ฉันจะเพิ่ม #myDiv ได้อย่างไรหากเงื่อนไขเป็นจริง ตัวอย่าง: ด้วย id ฉันสามารถทำได้ [id] = "isValid? 'myDiv': '' ขอบคุณ
daniel8x

77

คุณสามารถฉีดโทเค็นDOCUMENTลงในตัวสร้างและใช้ฟังก์ชันเดียวกันกับมันได้

import { Inject }  from '@angular/core';
import { DOCUMENT } from '@angular/common'; 

@Component({...})
export class AppCmp {
   constructor(@Inject(DOCUMENT) document) {
      document.getElementById('el');
   }
}

หรือถ้าองค์ประกอบที่คุณต้องการที่จะได้รับอยู่ในองค์ประกอบที่คุณสามารถใช้อ้างอิงแม่แบบ


เหตุใดฉันจึงควรฉีดอ็อบเจ็กต์เอกสารและไม่ใช้ที่จาวาสคริปต์ให้มาโดยตรง
Davide

@Davide เราอาศัยระบบของ Angular หลังจากนั้นพวกเขาสามารถใช้สิ่งที่ดีมากและตรวจสอบการใช้งาน ดังนั้นเราจึงอาศัยนามธรรมตรงนี้
สุเรนสราเรียน

24

สำหรับ Angular 8 หรือด้านหลัง @ViewChild มีพารามิเตอร์เพิ่มเติมที่เรียกว่าตัวเลือกซึ่งมีคุณสมบัติสองอย่าง: อ่านและแบบคงที่อ่านเป็นทางเลือก คุณสามารถใช้มันดังนี้:

// ...
@ViewChild('mydiv', { static: false }) public mydiv: ElementRef;

constructor() {
// ...
<div #mydiv></div>

หมายเหตุ: Static: false ไม่จำเป็นอีกต่อไปใน Angular 9 (เฉพาะ{ static: true }เมื่อคุณจะใช้ตัวแปรนั้นภายใน ngOnInit)


1
*ngIfมันทำงานได้เมื่อคุณแบบไดนามิกซ่อนหรือองค์ประกอบการแสดงโดยใช้ คุณกำลังสร้างองค์ประกอบอย่างไร
Gustavo Santamaría

8

ลองสิ่งนี้:

รหัสไฟล์ TypeScript:

(<HTMLInputElement> document.getElementById ("name")). value

รหัส HTML:

 <input id = "name" type = "text" #name /> 

7
  element: HTMLElement;

  constructor() {}

  fakeClick(){
    this.element = document.getElementById('ButtonX') as HTMLElement;
    this.element.click();
  }

4
สิ่งนี้ไม่ปลอดภัยมาก (การเรียกใช้คำสั่งนี้ใน Angular Universal ทำให้เกิดข้อขัดข้อง) และควรใช้เฉพาะในกรณีที่ไม่มีตัวเลือกอื่นที่เป็นไปได้ (โปรดพิจารณาว่าองค์ประกอบนั้นอาจไม่มีอยู่)
Joniras

3
M @ Joniras ทำไมถึงไม่ปลอดภัยมาก
Sumi Straessle
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.