Substituição de document.getElementById em angular4 / typescript?

95

Então, estou trabalhando com angular4 em meu trabalho prático e isso é novo para mim. Felizmente, para obter os elementos html e seus valores, usei <HTMLInputElement> document.getElementByIdou <HTMLSelectElement> document.getElementById

Estou me perguntando se há algum substituto para isso no angular

Nino Gutierrez
fonte
2
Por que não usar getElementById?
Suren Srapyan
Basta imaginar que existe uma maneira angular de obter elementos.
Nino Gutierrez

Respostas:

151

Você pode marcar seu elemento DOM usando e #someTag, em seguida, obtê-lo com @ViewChild('someTag').

Veja o exemplo completo:

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.logirá imprimir algum texto .

Alexandre Annic
fonte
O erro aparece Erro: Não é possível resolver '@ angular / core / src / metadata / di' Erro: Não é possível resolver '@ angular / core / src / linker / element_ref'
Nino Gutierrez
2
nvm, resolvido importando assim. import {Component, OnInit, ViewChild, ElementRef} de '@ angular / core';
Nino Gutierrez
20
não funcionará se você tiver um elemento dom condicional como * ngFor, * ngIf etc
Ravindra Thorat
Angular 8+ requer dois argumentos para o decorador ViewChild.
Como posso adicionar #myDiv apenas se uma condição for verdadeira? Por exemplo: com id, posso fazer [id] = "isValid? 'MyDiv': ''. Obrigado
daniel8x
77

Você pode simplesmente injetar o token DOCUMENT no construtor e usar as mesmas funções nele

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

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

Ou se o elemento que você deseja obter está nesse componente, você pode usar referências de modelo .

Suren Srapyan
fonte
Por que devo injetar o objeto de documento e não usar diretamente aquele fornecido pelo javascript?
Davide
@Davide contamos com o sistema da Angular. Mais tarde, eles podem implementar coisas muito boas e fazer algumas verificações em sua implementação. Portanto, apenas contamos com a abstração aqui
Suren Srapyan
24

Para Angular 8 ou posterior @ViewChild tem um parâmetro adicional chamado opts, que tem duas propriedades: read e static, read é opcional. Você pode usá-lo assim:

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

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

NOTA: Static: false não é mais necessário no Angular 9. (apenas { static: true }quando você vai usar essa variável dentro de ngOnInit)

Gustavo Santamaría
fonte
1
Funciona quando você oculta ou mostra elementos dinamicamente usando *ngIf. Como você está criando o elemento?
Gustavo Santamaría
8

Experimente isto:

Código do arquivo TypeScript:

(<HTMLInputElement> document.getElementById ("nome")). Valor

Código HTML:

 <input id = "name" type = "text" #name /> 
Swati
fonte
7
  element: HTMLElement;

  constructor() {}

  fakeClick(){
    this.element = document.getElementById('ButtonX') as HTMLElement;
    this.element.click();
  }
Cesar Devesa
fonte
4
Isso é muito inseguro (executar este comando no Angular Universal causa um travamento) e só deve ser usado se nenhuma outra opção for possível (considere também que o elemento pode não estar presente)
Joniras
3
M @ Joniras por que é muito inseguro?
Sumi Straessle