Angular @ ViewChild () -Fehler: 2 Argumente erwartet, aber 1

249

Beim Versuch mit ViewChild wird der Fehler angezeigt. Fehler ist "Ein Argument für 'opts' wurde nicht angegeben."

Beide @ViewChild geben den Fehler aus.

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): Fehler TS2554: 2 Argumente erwartet, aber 1 erhalten.

Paketüberfluss
quelle
Was steht in Zeile 11?
Tony Ngo
@TonyNgo @ViewChild ('nameInput') nameInputRef: ElementRef;
Stapelüberlauf

Antworten:

496

In Angular 8 akzeptiert ViewChild zwei Parameter

 @ViewChild(ChildDirective, {static: false}) Component
Jensen
quelle
9
Kannst du es bitte als akzeptiert markieren? Aus Angular-Dokumenten: statisch - Gibt an, ob Abfrageergebnisse aufgelöst werden sollen, bevor die Änderungserkennung ausgeführt wird (dh nur statische Ergebnisse zurückgeben). Wenn diese Option nicht bereitgestellt wird, greift der Compiler auf sein Standardverhalten zurück, bei dem Abfrageergebnisse verwendet werden, um den Zeitpunkt der Abfrageauflösung zu bestimmen. Wenn sich Abfrageergebnisse in einer verschachtelten Ansicht befinden (z. B. * ngIf), wird die Abfrage aufgelöst, nachdem die Änderungserkennung ausgeführt wurde. Andernfalls wird es behoben, bevor die Änderungserkennung ausgeführt wird.
Jensen
12
Sie sollten das der Antwort hinzufügen, wenn Sie möchten, dass er Ihre Antwort als die beste akzeptiert
Sytham
14
Hinweis: Um das Verhalten in Angular 7 beizubehalten, müssen Sie angeben { static: true }. ng updatehilft Ihnen dabei, dies bei Bedarf automatisch zu tun. Oder wenn Sie Ihre Abhängigkeiten bereits auf Angular 8 aktualisiert haben, hilft dieser Befehl bei der Migration Ihres Codes:ng update @angular/core --from 7 --to 8 --migrate-only
evilkos
11
Wenn das Element während ngOnInit verfügbar sein muss, muss es statisch sein true, aber wenn es bis nach dem Init warten kann false, kann es sein , was bedeutet, dass es erst ngAfterViewInit / ngAfterContentInit verfügbar sein wird.
Armen Zakaryan
Das wusste ich nicht. Vielen Dank. :-)
Tanzeel
84

Winkel 8

In Angular 8 verfügt ViewChild über einen weiteren Parameter

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

Hier und hier können Sie mehr darüber lesen

Winkel 9

Der Angular 9Standardwert ist static: false, muss also keinen Parameter angeben, es sei denn, Sie möchten verwenden{static: true}

Reza
quelle
In einem der Artikel, auf die Sie verlinkt haben, wird die Syntax wie folgt angezeigt @ContentChild('foo', {static: false}) foo !: ElementRef;. Ich bin gespannt auf das Ausrufezeichen. Ist das auch bei Angular 8 etwas Neues?
Konrad Viltersten
1
@KonradViltersten siehe diese stackoverflow.com/a/56950936/2279488
Reza
26

In Winkel 8 ViewChild 2 Parameter verwendet:

Versuchen Sie es so:

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

Erläuterung:

{statisch: falsch}

Wenn Sie static false festlegen , wird die Komponente IMMER nach der Ansichtsinitialisierung rechtzeitig für die ngAfterViewInit/ngAfterContentInitRückruffunktionen initialisiert .

{static: true}

Wenn Sie static true setzen , erfolgt die Initialisierung bei der Ansichtsinitialisierung umngOnInit

Standardmäßig können Sie verwenden { static: false } . Wenn Sie eine dynamische Ansicht erstellen und die Vorlagenreferenzvariable verwenden möchten, sollten Sie diese verwenden{ static: true}

Weitere Informationen finden Sie in diesem Artikel

Arbeitsdemo

In der Demo werden wir mithilfe der Vorlagenreferenzvariablen zu einem div scrollen.

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

Mit { static: true }, können wir verwenden this.scrollTo.nativeElementin ngOnInit, aber mit { static: false }, this.scrollTowird undefinedin ngOnInit, so dass wir nur Zugriff auf inngAfterViewInit

Adrita Sharma
quelle
6

Dies liegt daran, dass View Child zwei Argumente benötigt. Versuchen Sie es wie folgt

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

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

Paras Shah
quelle
3

In Angular 8 akzeptiert ViewChild immer 2 Parameter, und zweite Parameter haben immer static: true oder static: false

Sie können Folgendes versuchen:

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

Außerdem static: falsewird dies das Standard-Fallback-Verhalten in Angular 9 sein.

Was sind statisch falsch / wahr? Als Faustregel können Sie also Folgendes wählen:

  • { static: true } muss festgelegt werden, wenn Sie in ngOnInit auf ViewChild zugreifen möchten.

    { static: false }kann nur in ngAfterViewInit zugegriffen werden. Dies ist auch das, was Sie tun möchten, wenn Sie eine strukturelle Direktive (dh * ngIf) für Ihr Element in Ihrer Vorlage haben.

Pinki Dhakad
quelle
1

Regex zum Ersetzen aller über IDEA (getestet mit Webstorm)

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

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

Torsten Simon
quelle
1

Sie sollten das zweite Argument mit ViewChild wie folgt verwenden:

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

Benutze das

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

Dhilrukshan Pradeep
quelle
0

In Angular 8 verfügt ViewChild über einen weiteren Parameter

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

Ich habe mein Problem wie folgt gelöst

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

user2660331
quelle
-5

Das hat auch mein Problem gelöst.

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