Błąd kątowy @ViewChild (): oczekiwano 2 argumentów, ale otrzymał 1

249

Podczas próby ViewChild pojawia się błąd. Błąd brzmi: „Nie podano argumentu„ opts ”.”

Zarówno @ViewChild podaje błąd.

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): błąd TS2554: Oczekiwano 2 argumentów, ale otrzymał 1.

przepełnienie stosu
źródło
Co jest w linii 11?
Tony Ngo,
@TonyNgo @ViewChild ('nameInput') nameInputRef: ElementRef;
przepełnienie stosu

Odpowiedzi:

497

W Angular 8 ViewChild przyjmuje 2 parametry

 @ViewChild(ChildDirective, {static: false}) Component
Jensen
źródło
9
czy możesz zaznaczyć to jako zaakceptowane? From Angular docs: static - czy rozstrzygać wyniki zapytania przed uruchomieniem wykrywania zmian (tj. Zwracać tylko wyniki statyczne). Jeśli ta opcja nie zostanie podana, kompilator powróci do swojego domyślnego zachowania, polegającego na wykorzystaniu wyników zapytania w celu ustalenia czasu rozwiązania zapytania. Jeśli jakiekolwiek wyniki zapytania znajdują się w widoku zagnieżdżonym (np. * NgIf), zapytanie zostanie rozwiązane po uruchomieniu wykrywania zmian. W przeciwnym razie zostanie to rozwiązane przed uruchomieniem wykrywania zmian.
Jensen
12
Powinieneś dodać to do odpowiedzi, jeśli chcesz, aby zaakceptował twoją odpowiedź jako najlepszą
Sytham
14
Uwaga: aby zachować zachowanie, które miałeś w Angular 7, musisz określić { static: true }. ng updatepomoże ci to zrobić automatycznie w razie potrzeby. Lub, jeśli już zaktualizowałeś swoje zależności do Angular 8, to polecenie pomoże migrować kod:ng update @angular/core --from 7 --to 8 --migrate-only
evilkos
11
Jeśli element musi być dostępny podczas ngOnInit, to musi być statyczny true, ale jeśli może poczekać do inicjacji, może być false, co oznacza, że ​​nie będzie dostępny do ngAfterViewInit / ngAfterContentInit.
Armen Zakaryan
Nie wiedziałem tego Dzięki. :-)
Tanzeel
84

Kątowy 8

W Angular 8 ViewChild ma inny parametr

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

Możesz przeczytać więcej o tym tutaj i tutaj

Kątowy 9

W Angular 9Domyślną wartością jest static: false, więc nie ma potrzeby, aby zapewnić param chyba że chcesz używać{static: true}

Reza
źródło
W jednym z artykułów, do których linkujesz, mają one podobną składnię @ContentChild('foo', {static: false}) foo !: ElementRef;. Jestem ciekawy wykrzyknika. Czy to coś nowego w Angular 8?
Konrad Viltersten,
1
@KonradViltersten zobacz ten stackoverflow.com/a/56950936/2279488
Reza
26

W Angular 8 ViewChildprzyjmuje 2 parametry:

Spróbuj tak:

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

Wyjaśnienie:

{static: false}

Jeśli ustawisz wartość false na statyczną , komponent ZAWSZE zostanie zainicjowany po zainicjowaniu widoku w czasie dla ngAfterViewInit/ngAfterContentInitfunkcji wywołania zwrotnego.

{static: true}

Jeśli ustawisz wartość true true , inicjalizacja nastąpi przy inicjalizacji widoku o godziniengOnInit

Domyślnie możesz użyć { static: false }. Jeśli tworzysz widok dynamiczny i chcesz użyć zmiennej odwołania do szablonu, powinieneś użyć{ static: true}

Aby uzyskać więcej informacji, możesz przeczytać ten artykuł

Demo pracy

W wersji demonstracyjnej przewijamy do div przy użyciu zmiennej odniesienia szablonu.

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

Dzięki { static: true }, możemy użyć this.scrollTo.nativeElementw ngOnInit, ale { static: false }, this.scrollTobędzie undefinedsię ngOnInit, więc mamy dostęp jedynie wngAfterViewInit

Adrita Sharma
źródło
6

Dzieje się tak, ponieważ widok dziecka wymaga dwóch argumentów. Spróbuj tego

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

@ViewChild ('kwotaInput', {static: false,}) kwotaInputRef: ElementRef;

paras shah
źródło
3

W Angular 8 ViewChild zawsze przyjmuje 2 parametry, a drugie parametry zawsze mają statyczny: prawda lub statyczny: fałsz

Możesz spróbować w ten sposób:

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

Ponadto, static: falsebędzie domyślnym zachowaniem awaryjna w kątowym 9.

Co to jest statyczne fałsz / prawda: Z reguły można zastosować następujące zasady:

  • { static: true } należy ustawić, aby uzyskać dostęp do ViewChild w ngOnInit.

    { static: false }można uzyskać dostęp tylko w ngAfterViewInit. To jest również to, do czego chcesz się zastosować, gdy masz dyrektywę strukturalną (tj. * NgIf) na swoim elemencie w szablonie.

Pinki Dhakad
źródło
1

Regex w celu zastąpienia wszystkich za pośrednictwem IDEA (testowane za pomocą Webstorm)

Odnaleźć: \@ViewChild\('(.*)'\)

Zastąpić: \@ViewChild\('$1', \{static: true\}\)

Torsten Simon
źródło
1

powinieneś użyć drugiego argumentu z ViewChild w następujący sposób:

@ViewChild("eleDiv", { static: false }) someElement: ElementRef;
Hammad Ahmad
źródło
1

Użyj tego

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

Dhilrukshan Pradeep
źródło
0

W Angular 8 ViewChild ma inny parametr

@ViewChild („nameInput”, {static: false}) składnik

Rozwiązałem problem jak poniżej

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

użytkownik2660331
źródło
-5

To także rozwiązało mój problem.

@ViewChild('map', {static: false}) googleMap;
Helmar Bachle
źródło