Lỗi Angular @ViewChild (): Dự kiến ​​2 đối số, nhưng có 1


249

Khi dùng thử ViewChild tôi gặp lỗi. Lỗi là "Đối số cho 'opts' không được cung cấp."

Cả @ViewChild đều đưa ra lỗi.

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): lỗi TS2554: Dự kiến ​​2 đối số, nhưng có 1.


Có gì trong dòng 11?
Tony Ngô

@TonyNgo @ViewChild ('nameInput') nameInputRef: ElementRef;
chồng tràn

Câu trả lời:


497

Trong Angular 8, ViewChild có 2 tham số

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

9
bạn có thể vui lòng đánh dấu nó là chấp nhận? Từ tài liệu Angular: static - có hay không giải quyết kết quả truy vấn trước khi phát hiện thay đổi chạy (tức là chỉ trả về kết quả tĩnh). Nếu tùy chọn này không được cung cấp, trình biên dịch sẽ quay trở lại hành vi mặc định của nó, đó là sử dụng kết quả truy vấn để xác định thời gian giải quyết truy vấn. Nếu bất kỳ kết quả truy vấn nào nằm trong chế độ xem lồng nhau (ví dụ * ng If), truy vấn sẽ được giải quyết sau khi phát hiện thay đổi chạy. Nếu không, nó sẽ được giải quyết trước khi phát hiện thay đổi.
Jensen

12
Bạn nên thêm câu đó vào câu trả lời nếu bạn muốn anh ấy chấp nhận câu trả lời của bạn là câu trả lời hay nhất
Sytham

14
Lưu ý: để giữ hành vi bạn có trong Angular 7, bạn cần chỉ định { static: true }. ng updatesẽ giúp bạn làm điều này tự động khi cần thiết. Hoặc, nếu bạn đã nâng cấp các phụ thuộc của mình lên Angular 8, lệnh này sẽ giúp di chuyển mã của bạn:ng update @angular/core --from 7 --to 8 --migrate-only
evilkos

11
Nếu phần tử cần phải có sẵn trong ngOnInit, thì tĩnh cần phải có true, nhưng nếu nó có thể đợi cho đến sau khi init thì có thể false, điều đó có nghĩa là nó sẽ không khả dụng cho đến khi ngAfterViewInit / ngAfterContentInit.
Armen Zakaryan

Tôi không biết điều đó. Cảm ơn. :-)
Tanzania

84

Góc 8

Trong Angular 8, ViewChild có một thông số khác

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

Bạn có thể đọc thêm về nó ở đâyở đây

Góc 9

Trong Angular 9giá trị mặc định là static: false, vì vậy không cần cung cấp param trừ khi bạn muốn sử dụng{static: true}


Trong một trong những bài viết bạn liên kết đến, chúng hiển thị cú pháp như thế nào @ContentChild('foo', {static: false}) foo !: ElementRef;. Tôi tò mò về dấu chấm than. Đó có phải là một cái gì đó mới với Angular 8 không?
Konrad Viltersten

1
@KonradViltersten xem stackoverflow.com/a/56950936/2279488
Reza

26

Trong Angular 8, ViewChildcó 2 tham số:

Hãy thử như thế này:

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

Giải trình:

{tĩnh: sai}

Nếu bạn đặt tĩnh sai , thành phần LUÔN LUÔN được khởi tạo sau khi khởi tạo chế độ xem đúng lúc cho các ngAfterViewInit/ngAfterContentInithàm gọi lại.

{tĩnh: đúng}

Nếu bạn đặt tĩnh đúng , quá trình khởi tạo sẽ diễn ra ở chế độ xem khởi tạo tạingOnInit

Theo mặc định, bạn có thể sử dụng { static: false }. Nếu bạn đang tạo chế độ xem động và muốn sử dụng biến tham chiếu mẫu, thì bạn nên sử dụng{ static: true}

Để biết thêm thông tin, bạn có thể đọc bài viết này

Trình diễn làm việc

Trong bản demo, chúng tôi sẽ cuộn đến div bằng biến tham chiếu mẫu.

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

Với { static: true }, chúng ta có thể sử dụng this.scrollTo.nativeElementtrong ngOnInit, nhưng với { static: false }, this.scrollTosẽ undefinedtrong ngOnInit, vì vậy chúng tôi có thể truy cập trong chỉ trongngAfterViewInit


6

Đó là bởi vì con xem đòi hỏi hai đối số thử như thế này

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

@ViewChild ('moneyInput', {static: false,}) lượngInputRef: ElementRef;


3

Trong Angular 8, ViewChild luôn lấy 2 param và param thứ hai luôn có static: true hoặc static: false

Bạn có thể thử như thế này:

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

Ngoài ra, static: falseđây sẽ là hành vi dự phòng mặc định trong Angular 9.

Tĩnh sai / đúng là gì: Vì vậy, theo nguyên tắc thông thường, bạn có thể thực hiện các bước sau:

  • { static: true } cần được đặt khi bạn muốn truy cập ViewChild trong ngOnInit.

    { static: false }chỉ có thể được truy cập trong ngAfterViewInit. Đây cũng là những gì bạn muốn thực hiện khi bạn có một chỉ thị cấu trúc (tức là * ng If) trên phần tử của bạn trong mẫu của bạn.


1

Regex để thay thế tất cả thông qua IDEA (đã thử nghiệm với Webstorm)

Tìm thấy: \@ViewChild\('(.*)'\)

Thay thế: \@ViewChild\('$1', \{static: true\}\)


1

bạn nên sử dụng đối số thứ hai với ViewChild như thế này:

@ViewChild("eleDiv", { static: false }) someElement: ElementRef;


0

Trong Angular 8, ViewChild có một thông số khác

Thành phần @ViewChild ('nameInput', {static: false})

Tôi đã giải quyết vấn đề của mình như dưới đây

@ViewChild (MatSort, {static: false}) sắp xếp: MatSort;


-5

Điều đó cũng giải quyết vấn đề của tôi.

@ViewChild('map', {static: false}) googleMap;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.