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.


¿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

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}


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


6

es porque ver hijo requiere dos argumentos intente así

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

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


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.


1

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

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

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


1

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

@ViewChild("eleDiv", { static: false }) someElement: ElementRef;


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;


-5

Eso también resolvió mi problema.

@ViewChild('map', {static: false}) googleMap;
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.