Угловая ошибка @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

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;


0

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

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

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

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


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.