Chúng tôi có thể nhận được thông báo Property has no initializer and is not definitely assigned in the constructor
khi thêm một số cấu hình trong tsconfig.json
tệp để có một dự án Angular được biên dịch ở chế độ nghiêm ngặt:
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"noImplicitThis": true,
"alwaysStrict": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true,
Thật vậy, trình biên dịch sau đó phàn nàn rằng một biến thành viên không được định nghĩa trước khi được sử dụng.
Ví dụ về một biến thành viên không được xác định tại thời điểm biên dịch, một biến thành viên có một @Input
chỉ thị:
@Input() userId: string;
Chúng tôi có thể tắt tiếng trình biên dịch bằng cách nêu biến có thể là tùy chọn:
@Input() userId?: string;
Nhưng sau đó, chúng ta sẽ phải đối phó với trường hợp biến không được xác định và làm lộn xộn mã nguồn với một số câu lệnh như vậy:
if (this.userId) {
} else {
}
Thay vào đó, khi biết giá trị của biến thành viên này sẽ được xác định đúng lúc, tức là nó sẽ được định nghĩa trước khi được sử dụng, chúng ta có thể nói với trình biên dịch đừng lo lắng về việc nó không được định nghĩa.
Cách để thông báo điều này với trình biên dịch là thêm ! definite assignment assertion
toán tử, như trong:
@Input() userId!: string;
Bây giờ, trình biên dịch hiểu rằng biến này, mặc dù không được định nghĩa tại thời điểm biên dịch, nhưng sẽ được xác định tại thời điểm chạy và trong thời gian, trước khi nó được sử dụng.
Bây giờ ứng dụng phải đảm bảo biến này được xác định trước khi được sử dụng.
Như một biện pháp bảo vệ bổ sung, chúng tôi có thể khẳng định biến đang được xác định trước khi chúng tôi sử dụng.
Chúng ta có thể khẳng định biến đã được định nghĩa, nghĩa là, ràng buộc đầu vào bắt buộc đã thực sự được cung cấp bởi ngữ cảnh gọi:
private assertInputsProvided(): void {
if (!this.userId) {
throw (new Error("The required input [userId] was not provided"));
}
}
public ngOnInit(): void {
this.assertInputsProvided();
}
Biết biến đã được định nghĩa, biến bây giờ có thể được sử dụng:
ngOnChanges() {
this.userService.get(this.userId)
.subscribe(user => {
this.update(user.confirmedEmail);
});
}
Lưu ý rằng ngOnInit
phương thức được gọi sau khi các liên kết đầu vào cố gắng, điều này, ngay cả khi không có đầu vào thực tế nào được cung cấp cho các liên kết.
Trong khi ngOnChanges
phương thức được gọi sau khi các liên kết đầu vào cố gắng thực hiện và chỉ khi có đầu vào thực sự được cung cấp cho các liên kết.