Подтвердить что ты не робот

Angular: в котором жизненный цикл - это входные данные, доступные для компонента

У меня есть компонент, который получает массив объектов 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 не задано на этом этапе. Я также пробовал крюк 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>
...
4b9b3361

Ответ 1

Свойства ввода заполняются до вызова ngOnInit(). Однако это предполагает, что родительское свойство, которое передает входное свойство, уже заполняется при создании дочернего компонента.

В вашем сценарии это не тот случай – данные изображений заселяются асинхронно из службы (следовательно, HTTP-запрос). Следовательно, входное свойство не будет заселено при вызове ngOnInit().

Чтобы решить вашу проблему, когда данные возвращаются с сервера, назначьте новый массив родительскому свойству. Внесите ngOnChanges() в дочерний элемент. ngOnChanges() будет вызываться, когда обнаружение изменения Angular распространяет новое значение массива вниз до дочернего элемента.