Error angular @ViewChild (): se esperaban 2 argumentos, pero obtuve 1

249

Al intentar ViewChild obtengo el error. El error es "No se proporcionó un argumento para 'opts'".

Tanto @ViewChild está dando el error.

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): error TS2554: Se esperaban 2 argumentos, pero obtuve 1.

desbordamiento de pila
fuente
¿Qué hay en la línea 11?
Tony Ngo
@TonyNgo @ViewChild ('nameInput') nameInputRef: ElementRef;
desbordamiento de pila

Respuestas:

497

En Angular 8, ViewChild toma 2 parámetros

 @ViewChild(ChildDirective, {static: false}) Component
Jensen
fuente
99
¿puedes marcarlo como aceptado? Desde documentos angulares: estático: si se deben resolver o no los resultados de la consulta antes de que se ejecute la detección de cambios (es decir, solo devolver resultados estáticos). Si no se proporciona esta opción, el compilador recurrirá a su comportamiento predeterminado, que es utilizar los resultados de la consulta para determinar el momento de la resolución de la consulta. Si los resultados de alguna consulta están dentro de una vista anidada (por ejemplo, * ngIf), la consulta se resolverá después de que se ejecute la detección de cambios. De lo contrario, se resolverá antes de que se ejecute la detección de cambios.
Jensen
12
Debería agregar eso a la respuesta si desea que acepte su respuesta como la mejor
Sytham
14
Nota: para mantener el comportamiento que tenía en Angular 7, debe especificar { static: true }. ng updatele ayudará a hacer esto automáticamente donde sea necesario. O, si ya ha actualizado sus dependencias a Angular 8, este comando lo ayudará a migrar su código:ng update @angular/core --from 7 --to 8 --migrate-only
evilkos el
11
Si el elemento necesita estar disponible durante ngOnInit, entonces estático debe estarlo true, pero si puede esperar hasta después del inicio, puede estarlo false, lo que significa que no estará disponible hasta ngAfterViewInit / ngAfterContentInit.
Armen Zakaryan
No lo sabia. Gracias. :-)
Tanzeel
84

Angular 8

En Angular 8, ViewChild tiene otro parámetro

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

Puedes leer más sobre esto aquí y aquí

Angular 9

El Angular 9valor predeterminado es static: false, por lo que no necesita proporcionar parámetros a menos que desee usar{static: true}

Reza
fuente
En uno de los artículos a los que se vinculó, muestran sintaxis como @ContentChild('foo', {static: false}) foo !: ElementRef;. Tengo curiosidad por el signo de exclamación. ¿Es algo nuevo con Angular 8 también?
Konrad Viltersten
1
@KonradViltersten vea este stackoverflow.com/a/56950936/2279488
Reza
26

En Angular 8, ViewChildtoma 2 parámetros:

Intenta así:

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

Explicación:

{estática: falso}

Si establece false estático , el componente SIEMPRE se inicializa después de la inicialización de la vista a tiempo para las ngAfterViewInit/ngAfterContentInitfunciones de devolución de llamada.

{static: true}

Si establece true estático , la inicialización tendrá lugar en la inicialización de la vista enngOnInit

Por defecto puedes usar { static: false }. Si está creando una vista dinámica y desea usar la variable de referencia de plantilla, entonces debe usar{ static: true}

Para más información, puedes leer este artículo

Demo de trabajo

En la demostración, nos desplazaremos a un div usando la variable de referencia de plantilla.

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

Con { static: true }, podemos usar this.scrollTo.nativeElementen ngOnInit, pero con { static: false }, this.scrollToestará undefineden ngOnInit, por lo que podemos acceder solo enngAfterViewInit

Adrita Sharma
fuente
6

es porque ver hijo requiere dos argumentos intente así

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

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

paras shah
fuente
3

En Angular 8, ViewChild siempre toma 2 parámetros, y el segundo parámetro siempre tiene static: true o static: false

Puedes intentarlo así:

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

Además, static: falseserá el comportamiento de reserva predeterminado en Angular 9.

Qué es estático falso / verdadero: por lo tanto, como regla general, puede elegir lo siguiente:

  • { static: true } debe configurarse cuando desee acceder a ViewChild en ngOnInit.

    { static: false }solo se puede acceder en ngAfterViewInit. Esto también es lo que desea utilizar cuando tiene una directiva estructural (es decir, * ngIf) en su elemento en su plantilla.

Pinki Dhakad
fuente
1

Regex para reemplazar todo a través de IDEA (probado con Webstorm)

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

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

Torsten Simon
fuente
1

deberías usar el segundo argumento con ViewChild así:

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

Utilizar este

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

Dhilrukshan Pradeep
fuente
0

En Angular 8, ViewChild tiene otro parámetro

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

Resolví mi problema como a continuación

@ViewChild (MatSort, {static: false}) sort: MatSort;

usuario2660331
fuente
-5

Eso también resolvió mi problema.

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