ค้นหาเว็บไซต์

javascript - Angular: ใน hook ของ lifecycle ไหนที่ข้อมูล input สามารถเข้าถึงได้ใน Component


ฉันมีคอมโพเนนต์ที่รับอาร์เรย์ของวัตถุ image เป็นข้อมูล Input

export class ImageGalleryComponent {
  @Input() images: Image[];
  selectedImage: Image;
}

ฉันต้องการให้เมื่อคอมโพเนนต์โหลด ค่า selectedImage ถูกตั้งค่าเป็นวัตถุตัวแรกของอาร์เรย์ images ฉันได้ลองทำสิ่งนี้ในฮุกวงจรชีวิต OnInit แบบนี้:

export class ImageGalleryComponent implements OnInit {
  @Input() images: Image[];
  selectedImage: Image;
  ngOnInit() {
    this.selectedImage = this.images[0];
  }
}

นี่ทำให้ฉันเกิดข้อผิดพลาด Cannot read property '0' of undefined ซึ่งหมายความว่าค่า images ยังไม่ได้ถูกตั้งค่าในขั้นตอนนี้ ฉันก็ได้ลองใช้ hook OnChanges แล้ว แต่ฉันติดขัดเพราะไม่สามารถหาข้อมูลเกี่ยวกับการสังเกตการเปลี่ยนแปลงของอาร์เรย์ได้ ฉันจะทำอย่างไรเพื่อให้ได้ผลลัพธ์ตามที่คาดหวัง?

คอมโพเนนต์หลักมีลักษณะดังนี้:

@Component({
  selector: 'profile-detail',
  templateUrl: '...',
  styleUrls: [...],
  directives: [ImageGalleryComponent]
})

export class ProfileDetailComponent implements OnInit {
  profile: Profile;
  errorMessage: string;
  images: Image[];
  constructor(private profileService: ProfileService, private   routeParams: RouteParams){}

  ngOnInit() {
    this.getProfile();
  }

  getProfile() {
    let profileId = this.routeParams.get('id');
    this.profileService.getProfile(profileId).subscribe(
    profile => {
     this.profile = profile;
     this.images = profile.images;
     for (var album of profile.albums) {
       this.images = this.images.concat(album.images);
     }
    }, error => this.errorMessage = <any>error
   );
 }
}

แม่แบบของส่วนประกอบหลักมีสิ่งนี้

...
<image-gallery [images]="images"></image-gallery>
...

คำตอบ #1

คุณสมบัติของอินพุตจะถูกเติมก่อนที่ ngOnInit() จะถูกเรียก อย่างไรก็ตาม สิ่งนี้สมมติว่าคุณสมบัติของพ่อแม่ที่ป้อนให้คุณสมบัติอินพุตนั้นถูกเติมแล้วเมื่อคอมโพเนนต์ลูกถูกสร้างขึ้น

ในสถานการณ์ของคุณ ไม่เป็นเช่นนั้น - ข้อมูลภาพกำลังถูกเติมแบบอะซิงโครนัสจากบริการ (ดังนั้นจึงเป็นการร้องขอ http) ดังนั้น property ของ input จะยังไม่ถูกเติมเมื่อ ngOnInit() ถูกเรียก

ในการแก้ปัญหาของคุณ เมื่อข้อมูลถูกส่งกลับมาจากเซิร์ฟเวอร์ ให้กำหนดอาร์เรย์ใหม่ให้กับคุณสมบัติของพาเรนต์ นำ ngOnChanges() ไปใช้งานในชิลด์ ngOnChanges() จะถูกเรียกเมื่อการตรวจจับการเปลี่ยนแปลงของ Angular ส่งค่าของอาร์เรย์ใหม่ลงไปยังชิลด์

คำตอบ #2

คุณยังสามารถเพิ่มตัวตั้งค่าสำหรับรูปภาพของคุณซึ่งจะถูกเรียกทุกครั้งที่ค่ามีการเปลี่ยนแปลง และคุณสามารถตั้งค่ารูปภาพเริ่มต้นที่เลือกในตัวตั้งค่าเองได้:

export class ImageGalleryComponent {
  private _images: Image[];

  @Input()
  set images(value: Image[]) {
      if (value) { //null check
          this._images = value;
          this.selectedImage = value[0]; //setting default selected image
      }
  }
  get images(): Image[] {
      return this._images;
  }

  selectedImage: Image;
}

บทความที่เกี่ยวข้อง