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>
...
Ответы
Ответ 1
Свойства ввода заполняются до вызова ngOnInit()
. Однако это предполагает, что родительское свойство, которое передает входное свойство, уже заполняется при создании дочернего компонента.
В вашем сценарии это не тот случай – данные изображений заселяются асинхронно из службы (следовательно, HTTP-запрос). Следовательно, входное свойство не будет заселено при вызове ngOnInit()
.
Чтобы решить вашу проблему, когда данные возвращаются с сервера, назначьте новый массив родительскому свойству. Внесите ngOnChanges()
в дочерний элемент. ngOnChanges()
будет вызываться, когда обнаружение изменения Angular распространяет новое значение массива вниз до дочернего элемента.