Erro angular @ViewChild (): Esperado 2 argumentos, mas obteve 1

249

Ao tentar o ViewChild, estou recebendo o erro. O erro é "Não foi fornecido um argumento para 'opts'".

O @ViewChild está dando o erro.

import { Component, OnInit, ElementRef, ViewChild, Output, EventEmitter } from '@angular/core';
import { Ingredient } from 'src/app/shared/ingredient.model';

@Component({
  selector: 'app-shopping-edit',
  templateUrl: './shopping-edit.component.html',
  styleUrls: ['./shopping-edit.component.css']
})
export class ShoppingEditComponent implements OnInit {

@ViewChild('nameInput') nameInputRef: ElementRef;
@ViewChild('amountInput') amountInputRef: ElementRef;
@Output() ingredientAdded = new EventEmitter<Ingredient>();
  constructor() {}

  ngOnInit() {
  }

  onAddItem() {
    const ingName = this.nameInputRef.nativeElement.value;
    const ingAmount = this.amountInputRef.nativeElement.value;
    const newIngredient = new Ingredient(ingName, ingAmount);
    this.ingredientAdded.emit(newIngredient);
  }

}

ts (11,2): erro TS2554: Esperava 2 argumentos, mas obteve 1.

estouro de pilha
fonte
O que está na linha 11?
Tony Ngo
@TonyNgo @ViewChild ('nameInput') nameInputRef: ElementRef;
stack overflow

Respostas:

497

No Angular 8, o ViewChild usa 2 parâmetros

 @ViewChild(ChildDirective, {static: false}) Component
Jensen
fonte
9
você pode marcá-lo como aceito? De documentos angulares: estático - se deve ou não resolver os resultados da consulta antes da execução da detecção de alterações (por exemplo, retornar apenas resultados estáticos). Se essa opção não for fornecida, o compilador retornará ao seu comportamento padrão, que é usar os resultados da consulta para determinar o tempo da resolução da consulta. Se algum resultado da consulta estiver dentro de uma exibição aninhada (por exemplo, * ngIf), a consulta será resolvida após a execução da detecção de alterações. Caso contrário, ele será resolvido antes da execução da detecção de alterações.
Jensen
12
Você deve adicionar isso à resposta se quiser que ele aceite sua resposta como a melhor resposta
Sytham 16/09/1919
14
Nota: para manter o comportamento que você teve no Angular 7, você precisa especificar { static: true }. ng updateajudará você a fazer isso automaticamente sempre que necessário. Ou, se você já tiver atualizado suas dependências para Angular 8, este comando irá ajudar a migrar seu código:ng update @angular/core --from 7 --to 8 --migrate-only
evilkos
11
Se o elemento precisar estar disponível durante o ngOnInit, a estática precisará estar true, mas se puder esperar até depois do init false, o que significa que não estará disponível até ngAfterViewInit / ngAfterContentInit.
Armen Zakaryan
Eu não sabia disso. Obrigado. :-)
Tanzeel 13/01
84

Angular 8

No Angular 8, o ViewChild possui outro parâmetro

@ViewChild('nameInput', {static: false}) component

Você pode ler mais sobre isso aqui e aqui

Angular 9

No Angular 9valor padrão static: false, é , portanto, não é necessário fornecer parâmetros, a menos que você queira usar{static: true}

Reza
fonte
Em um dos artigos aos quais você vinculou, eles mostram sintaxe semelhante @ContentChild('foo', {static: false}) foo !: ElementRef;. Estou curioso sobre o ponto de exclamação. Isso também é algo novo no Angular 8?
Konrad Viltersten
1
@KonradViltersten veja este stackoverflow.com/a/56950936/2279488
Reza
26

No Angular 8, são ViewChildnecessários 2 parâmetros:

Tente assim:

@ViewChild('nameInput', { static: false }) nameInputRef: ElementRef;

Explicação:

{static: false}

Se você definir estático false , o componente SEMPRE será inicializado após a inicialização da exibição no tempo das ngAfterViewInit/ngAfterContentInitfunções de retorno de chamada.

{static: true}

Se você definir static true , a inicialização ocorrerá na visualização de inicialização emngOnInit

Por padrão, você pode usar { static: false }. Se você estiver criando uma visualização dinâmica e desejar usar a variável de referência do modelo, deverá usar{ static: true}

Para mais informações, você pode ler este artigo

Demonstração de trabalho

Na demonstração, rolaremos para uma div usando a variável de referência do modelo.

 @ViewChild("scrollDiv", { static: true }) scrollTo: ElementRef;

Com { static: true }, podemos usar this.scrollTo.nativeElementin ngOnInit, mas with { static: false }, this.scrollToestará undefinedin ngOnInit, para que possamos acessar somente emngAfterViewInit

Adrita Sharma
fonte
6

é porque view child requer dois argumentos e tente assim

@ViewChild ('nameInput', {static: false,}) nameInputRef: ElementRef;

@ViewChild ('amountInput', {static: false,}) amountInputRef: ElementRef;

paras shah
fonte
3

No Angular 8, o ViewChild sempre usa 2 parâmetros e o segundo parâmetro sempre tem static: true ou static: false

Você pode tentar assim:

@ViewChild('nameInput', {static: false}) component

Além disso, esse static: falseserá o comportamento de fallback padrão no Angular 9.

O que é estático false / true: Portanto, como regra geral, você pode fazer o seguinte:

  • { static: true } precisa ser definido quando você deseja acessar o ViewChild no ngOnInit.

    { static: false }só pode ser acessado em ngAfterViewInit. Também é isso que você deseja quando tiver uma diretiva estrutural (por exemplo, * ngIf) no seu elemento no seu modelo.

Pinki Dhakad
fonte
1

Regex para substituir tudo via IDEA (testado com Webstorm)

Encontrar: \@ViewChild\('(.*)'\)

Substituir: \@ViewChild\('$1', \{static: true\}\)

Torsten Simon
fonte
1

você deve usar o segundo argumento com o ViewChild assim:

@ViewChild("eleDiv", { static: false }) someElement: ElementRef;
Hammad Ahmad
fonte
1

Usa isto

Componente @ViewChild (ChildDirective, {static: false})

Dhilrukshan Pradeep
fonte
0

No Angular 8, o ViewChild possui outro parâmetro

Componente @ViewChild ('nameInput', {static: false})

Resolvi meu problema como abaixo

@ViewChild (MatSort, {estático: false}) sort: MatSort;

user2660331
fonte
-5

Isso também resolveu meu problema.

@ViewChild('map', {static: false}) googleMap;
Helmar Bachle
fonte