เราอาจได้รับข้อความProperty has no initializer and is not definitely assigned in the constructor
เมื่อเพิ่มการกำหนดค่าบางอย่างในtsconfig.json
ไฟล์เพื่อให้มีการคอมไพล์โครงการ Angular ในโหมดเข้มงวด:
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"noImplicitThis": true,
"alwaysStrict": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true,
จากนั้นคอมไพเลอร์ก็บ่นว่าไม่ได้กำหนดตัวแปรสมาชิกก่อนที่จะใช้
ตัวอย่างของตัวแปรสมาชิกที่ไม่ได้กำหนดไว้ในเวลาคอมไพล์ตัวแปรสมาชิกที่มี@Input
คำสั่ง:
@Input() userId: string;
เราสามารถปิดเสียงคอมไพเลอร์ได้โดยระบุว่าตัวแปรอาจเป็นทางเลือก:
@Input() userId?: string;
แต่จากนั้นเราจะต้องจัดการกับกรณีของตัวแปรที่ไม่ได้กำหนดไว้และทำให้ซอร์สโค้ดยุ่งเหยิงด้วยคำสั่งดังกล่าว:
if (this.userId) {
} else {
}
ในทางกลับกันการรู้ค่าของตัวแปรสมาชิกนี้จะถูกกำหนดตามเวลานั่นคือจะถูกกำหนดก่อนที่จะใช้เราสามารถบอกคอมไพเลอร์ได้ว่าอย่ากังวลว่าจะไม่ถูกกำหนด
วิธีบอกสิ่งนี้กับคอมไพเลอร์คือการเพิ่มไฟล์ ! definite assignment assertion
ดำเนินการดังใน:
@Input() userId!: string;
ตอนนี้คอมไพลเลอร์เข้าใจว่าตัวแปรนี้แม้ว่าจะไม่ได้กำหนดไว้ในเวลาคอมไพล์ แต่จะต้องถูกกำหนดที่รันไทม์และในเวลาก่อนที่จะถูกใช้
ตอนนี้ขึ้นอยู่กับแอปพลิเคชันแล้วว่าต้องกำหนดตัวแปรนี้ก่อนที่จะใช้
เพื่อเป็นการป้องกันเพิ่มเติมเราสามารถยืนยันได้ว่ามีการกำหนดตัวแปรก่อนที่เราจะใช้งาน
เราสามารถยืนยันได้ว่าตัวแปรถูกกำหนดไว้นั่นคือการเชื่อมโยงอินพุตที่ต้องการนั้นได้มาจากบริบทการเรียก
private assertInputsProvided(): void {
if (!this.userId) {
throw (new Error("The required input [userId] was not provided"));
}
}
public ngOnInit(): void {
this.assertInputsProvided();
}
เมื่อทราบตัวแปรถูกกำหนดแล้วสามารถใช้ตัวแปรได้:
ngOnChanges() {
this.userService.get(this.userId)
.subscribe(user => {
this.update(user.confirmedEmail);
});
}
โปรดทราบว่าngOnInit
เมธอดนี้ถูกเรียกใช้หลังจากความพยายามในการเชื่อมโยงอินพุตซึ่งแม้ว่าจะไม่มีการป้อนข้อมูลจริงให้กับการเชื่อมโยงก็ตาม
ในขณะที่ngOnChanges
เมธอดถูกเรียกหลังจากความพยายามในการเชื่อมโยงอินพุตและเฉพาะในกรณีที่มีอินพุตจริงที่จัดเตรียมไว้ให้กับการโยง