角@ViewChild()错误:预期有2个参数,但得到1个


248

尝试使用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行是什么?
Tony Ngo,

@TonyNgo @ViewChild('nameInput')nameInputRef:ElementRef;
堆栈溢出

Answers:


495

在Angular 8中,ViewChild采用2个参数

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

9
您可以将其标记为已接受吗?来自Angular docs:静态-是否在更改检测运行之前解析查询结果(即仅返回静态结果)。如果未提供此选项,则编译器将退回到其默认行为,即使用查询结果来确定查询解析的时间。如果任何查询结果在嵌套视图中(例如* 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期间可用,则static需要为true,但如果它可以等到init之后才可以false,那么这意味着直到ngAfterViewInit / ngAfterContentInit才可用。
亚美·扎卡良

我不知道 谢谢。:-)
Tanzeel

84

角度8

在Angular 8中,ViewChild具有另一个参数

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

您可以在这里这里了解更多

角度9

Angular 9默认值static: false,因此不需要,除非你想使用提供PARAM{static: true}


在您链接到的一篇文章中,它们显示的语法类似于@ContentChild('foo', {static: false}) foo !: ElementRef;。我对感叹号感到好奇。Angular 8也有新功能吗?
Konrad Viltersten

1
@KonradViltersten看到这个stackoverflow.com/a/56950936/2279488
Reza

26

在Angular 8中,ViewChild采用2个参数:

尝试这样:

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

说明:

{静态:假}

如果将static设置为false,则组件ALWAYS将在视图初始化之后及时为ngAfterViewInit/ngAfterContentInit回调函数初始化。

{静态:正确}

如果将static设置为true,则初始化将在视图初始化处进行ngOnInit

默认情况下,您可以使用{ static: false }。如果要创建动态视图并想使用模板引用变量,则应使用{ static: true}

有关更多信息,您可以阅读本文

工作演示

在演示中,我们将使用模板引用变量滚动到div。

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

使用{ static: true },我们可以this.scrollTo.nativeElement在中使用ngOnInit,但是使用{ static: false }this.scrollTo将在undefinedngOnInit,因此我们只能在中使用ngAfterViewInit


6

这是因为视图子需要两个参数尝试这样

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

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


3

在Angular 8中,ViewChild始终采用2个参数,第二个参数始终具有 static:truestatic:false

您可以这样尝试:

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

此外,这static: false将成为Angular 9中的默认后备行为。

什么是静态的false / true:因此,根据经验,您可以进行以下操作:

  • { static: true } 要在ngOnInit中访问ViewChild时需要设置。

    { static: false }只能在ngAfterViewInit中访问。当模板中的元素上具有结构化指令(即* ngIf)时,这也是您要追求的目标。


1

通过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})排序:MatSort;


-5

那也解决了我的问题。

@ViewChild('map', {static: false}) googleMap;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.