Угловая ошибка @ViewChild (): ожидается 2 аргумента, но получено 1

249

При попытке ViewChild я получаю сообщение об ошибке. Ошибка: «Не указан аргумент для« opts ».»

Оба @ViewChild выдает ошибку.

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): ошибка TS2554: ожидается 2 аргумента, но получено 1.

переполнение стека
источник
Что в строке 11?
Тони Нго
@TonyNgo @ViewChild ('nameInput') nameInputRef: ElementRef;
переполнение стека

Ответы:

497

В Angular 8 ViewChild принимает 2 параметра

 @ViewChild(ChildDirective, {static: false}) Component
Jensen
источник
9
Можете ли вы отметить его как принятый? From Angular docs: static - разрешать или не разрешать результаты запроса перед выполнением обнаружения изменений (т.е. возвращать только статические результаты). Если эта опция не предоставлена, компилятор вернется к своему поведению по умолчанию, которое будет использовать результаты запроса для определения времени разрешения запроса. Если какие-либо результаты запроса находятся во вложенном представлении (например, * ngIf), запрос будет разрешен после выполнения обнаружения изменений. В противном случае оно будет разрешено до запуска обнаружения изменений.
Дженсен
12
Вы должны добавить это к ответу, если хотите, чтобы он принял ваш ответ как лучший
Sytham
14
Примечание: чтобы сохранить поведение, которое вы имели в Angular 7, вам нужно указать { static: true }. ng updateпоможет вам сделать это автоматически, где это необходимо. Или, если вы уже обновили свои зависимости до Angular 8, эта команда поможет перенести ваш код:ng update @angular/core --from 7 --to 8 --migrate-only
evilkos
11
Если элемент должен быть доступен во время ngOnInit, то статический должен быть true, но если он может ждать до окончания инициализации, это falseозначает, что он не будет доступен до ngAfterViewInit / ngAfterContentInit.
Армен Закарян
Я этого не знал. Спасибо. :-)
Tanzeel
84

Угловой 8

В Angular 8 у ViewChild есть еще один параметр

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

Вы можете прочитать больше об этом здесь и здесь

Угловой 9

По Angular 9умолчанию значение равно static: false, поэтому не нужно указывать параметр, если вы не хотите использовать{static: true}

Реза
источник
В одной из статей, на которые вы ссылаетесь, они показывают синтаксис вроде @ContentChild('foo', {static: false}) foo !: ElementRef;. Мне любопытно насчет восклицательного знака. Это что-то новое с Angular 8 тоже?
Конрад Вилтерстен
1
@KonradViltersten посмотреть этот stackoverflow.com/a/56950936/2279488
Реза
26

В Angular 8 ViewChildпринимает 2 параметра:

Попробуйте вот так:

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

Объяснение:

{static: false}

Если вы установите статическое значение false , компонент ALWAYS будет инициализирован после инициализации представления во времени для ngAfterViewInit/ngAfterContentInitфункций обратного вызова.

{static: true}

Если вы установите static true , инициализация будет происходить при инициализации представления вngOnInit

По умолчанию вы можете использовать { static: false }. Если вы создаете динамическое представление и хотите использовать переменную ссылки на шаблон, вам следует использовать{ static: true}

Для получения дополнительной информации, вы можете прочитать эту статью

Рабочая Демо

В демоверсии мы перейдем к элементу div, используя переменную ссылки на шаблон.

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

С { static: true }, мы можем использовать this.scrollTo.nativeElementв ngOnInit, но с { static: false }, this.scrollToбудет undefinedв ngOnInit, поэтому мы можем получить доступ только вngAfterViewInit

Адрита Шарма
источник
6

это потому, что вид ребенка требует два аргумента, попробуйте так

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

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

парас шах
источник
3

В Angular 8 ViewChild всегда принимает 2 параметра, а второй параметр всегда имеет static: true или static: false

Вы можете попробовать так:

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

Кроме того, static: falseв Angular 9 будет использоваться стандартное аварийное поведение.

Что такое статическое ложное / истинное: так что, как правило, вы можете пойти на следующее:

  • { static: true } должен быть установлен, когда вы хотите получить доступ к ViewChild в ngOnInit.

    { static: false }можно получить доступ только в ngAfterViewInit. Это также то, к чему вы хотите стремиться, когда у вас есть структурная директива (т.е. * ngIf) для вашего элемента в шаблоне.

Пинки Дхакад
источник
1

Regex для замены всего через IDEA (протестировано с Webstorm)

Найти: \@ViewChild\('(.*)'\)

Заменить: \@ViewChild\('$1', \{static: true\}\)

Торстен Саймон
источник
1

Вы должны использовать второй аргумент с ViewChild следующим образом:

@ViewChild("eleDiv", { static: false }) someElement: ElementRef;
Хаммад ахмад
источник
1

Использовать это

Компонент @ViewChild (ChildDirective, {static: false})

Дилрукшан Прадип
источник
0

В Angular 8 у ViewChild есть еще один параметр

Компонент @ViewChild ('nameInput', {static: false})

Я решил свою проблему, как показано ниже

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

user2660331
источник
-5

Это также решило мою проблему.

@ViewChild('map', {static: false}) googleMap;
Хельмар Бахле
источник