Angular : 라이프 사이클 후크가 컴포넌트에 사용할 수있는 입력 데이터입니다.


82

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
images상위 구성 요소에 데이터가 어떻게 채워 집니까? 즉, http 요청을 통한 것입니까? 그렇다면 ImageGalleryComponent가 http Observable에 subscribe ()하는 것이 더 나을 수 있습니다.
Mark Rajcok

@MarkRajcok images은 이와 같이 부모가 사용하는 데이터의 일부일뿐입니다. {profile: {firstName: "abc", lastName: "xyz", images: [ ... ]}}즉, 자녀를 구독하면 부모를 구독해야하며 반복을 피하고 싶습니다
Optimus Pette

자식 구성 요소가 생성 될 때 부모 구성 요소의 이미지 배열이 채워지면 ngOnInit ()가 호출되기 전에 이미지 입력 ​​속성을 채워야합니다. 추가로 도움을 줄 수 있도록 부모 구성 요소에 이미지 배열이 채워지는 방법에 대한 자세한 정보를 제공해야합니다 (또는 문제를 보여주는 최소한의 Plunker 생성).
Mark Rajcok

@MarkRajcok 부모 구성 요소와 이미지가 채워지는 방식을 추가했습니다.
Optimus Pette 2016-06-24

2
예, 부모 구성 요소가 (서비스를 사용하고 있기 때문에) http를 사용하여 이미지 속성을 채우는 것처럼 보입니다. 이것은 비동기 작업이므로 자식 구성 요소의 입력 속성은 ngOnInit () 메서드가 호출 될 때까지 채워지지 않습니다. 코드를 ngOnInit ()에서 ngOnChanges ()로 이동하면 작동합니다.
Mark Rajcok

답변:


84

ngOnInit()호출 하기 전에 입력 속성이 채워집니다 . 그러나 이는 하위 구성 요소가 생성 될 때 입력 속성을 제공하는 상위 속성이 이미 채워져 있다고 가정합니다.

시나리오에서는 그렇지 않습니다. 이미지 데이터가 서비스 (따라서 http 요청)에서 비동기 적으로 채워집니다. 따라서를 ngOnInit()호출 할 때 입력 속성이 채워지지 않습니다 .

문제를 해결하려면 서버에서 데이터가 반환 될 때 부모 속성에 새 배열을 할당합니다. ngOnChanges()아이에게 구현 하십시오. ngOnChanges()Angular change detection이 새로운 배열 값을 자식에게 전파 할 때 호출됩니다.


1
저도 같은 문제에 직면했기 때문에 동의합니다. ngOnchanges()아이에게 구현 한 후에도 오류 Cannot read property '0' of undefined가 발생 합니다. 그러나 앱은 문제없이 계속 될 수 있습니다. 이 오류는 처음에 입력 속성이 채워지지 않았기 때문에 발생합니다. ngOnChanges()비동기 호출에서 데이터가 수신 될 때 두 번째 호출로 채워집니다 . 제 경우에는이 솔루션에 추가로 html 에 null 연산자에 대한 가드를 추가했습니다 . 오류가 명확하게 해결되었습니다.
Thilina Samiddhi

5

값이 변경 될 때마다 호출되는 이미지에 대한 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;
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.