Angular:生命周期钩子是Component可用的输入数据

Opt*_*tte 62 javascript typescript angular

我有一个组件接收一个image对象数组作为Input数据.

export class ImageGalleryComponent {
  @Input() images: Image[];
  selectedImage: Image;
}
Run Code Online (Sandbox Code Playgroud)

我想在组件加载时将selectedImage值设置为images数组的第一个对象.我试图在OnInit生命周期钩子中这样做:

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

这给了我一个错误Cannot read property '0' of undefined,这意味着images在这个阶段没有设置值.我也尝试了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
   );
 }
}
Run Code Online (Sandbox Code Playgroud)

父组件的模板具有此功能

...
<image-gallery [images]="images"></image-gallery>
...
Run Code Online (Sandbox Code Playgroud)

Mar*_*cok 63

ngOnInit()调用之前填充输入属性.但是,这假定在创建子组件时已填充了提供输入属性的父属性.

在您的方案中,情况并非如此 - 图像数据正在从服务异步填充(因此是http请求).因此,ngOnInit()调用时不会填充输入属性.

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


Sac*_*har 9

您还可以为您的图像添加一个设置器,每当值更改时都会调用该设置器,您可以在设置器本身中设置默认选择的图像:

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;
}
Run Code Online (Sandbox Code Playgroud)


小智 6

您只需更改一些内容即可解决此问题。

  export class ImageGalleryComponent implements OnInit, OnChanges {

  @Input() images: Image[];
  selectedImage: Image;

  ngOnChanges() {
      if(this.images) {
        this.selectedImage = this.images[0];
      }
  }

 }
Run Code Online (Sandbox Code Playgroud)

  • 注意,您需要添加“implements OnChanges”才能使用“ngOnChanges()”方法。 (2认同)