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>
...
답변
를 ngOnInit()
호출 하기 전에 입력 속성이 채워집니다 . 그러나 이는 하위 구성 요소가 생성 될 때 입력 속성을 제공하는 상위 속성이 이미 채워져 있다고 가정합니다.
시나리오에서는 그렇지 않습니다. 이미지 데이터가 서비스 (따라서 http 요청)에서 비동기 적으로 채워집니다. 따라서를 ngOnInit()
호출 할 때 입력 속성이 채워지지 않습니다 .
문제를 해결하려면 서버에서 데이터가 반환 될 때 부모 속성에 새 배열을 할당합니다. ngOnChanges()
아이에게 구현 하십시오. ngOnChanges()
Angular change detection이 새로운 배열 값을 자식에게 전파 할 때 호출됩니다.
답변
값이 변경 될 때마다 호출되는 이미지에 대한 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;
}