角度:其中生命周期钩子是组件可用的输入数据

2022-08-30 05:35:25

我有一个组件,它接收一个对象数组作为数据。imageInput

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

我希望当组件加载时,将值设置为数组的第一个对象。我试图在生命周期钩子中这样做,如下所示:selectedImageimagesOnInit

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

这给了我一个错误,这意味着该值未在此阶段设置。我也尝试过这个钩子,但我卡住了,因为我无法获得有关如何观察数组变化的信息。如何达到预期效果?Cannot read property '0' of undefinedimagesOnChanges

父组件如下所示:

@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 请求)。因此,调用时不会填充输入属性。ngOnInit()

若要解决您的问题,当从服务器返回数据时,将新数组分配给父属性。在孩子身上实施。 当角度变化检测将新数组值向下传播到子项时,将调用该值。ngOnChanges()ngOnChanges()


答案 2

您还可以为图像添加一个 setter,只要值更改,就会调用该 setter,您可以在 setter 本身中设置默认选择的图像:

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;
}