web-dev-qa-db-fra.com

Angular: Dans quel cycle de cycle de vie des données d’entrée sont disponibles pour le composant

J'ai un composant qui reçoit un tableau d'objets image sous la forme Inputdonnées.

export class ImageGalleryComponent {
  @Input() images: Image[];
  selectedImage: Image;
}

Je voudrais que lorsque le composant charge la valeur selectedImage soit définie sur le premier objet du tableau images. J'ai essayé de faire cela dans le hook OnInit lifecycle comme ceci:

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

cela me donne une erreur Cannot read property '0' of undefined ce qui signifie que la valeur images n’est pas définie sur cette étape. J'ai aussi essayé le hook OnChanges mais je suis bloqué car je ne peux pas obtenir d'informations sur la manière d'observer les modifications d'un tableau. Comment puis-je atteindre le résultat attendu?

Le composant parent ressemble à ceci:

@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
   );
 }
}

Le modèle du composant parent a ceci

...
<image-gallery [images]="images"></image-gallery>
...
61
Optimus Pette

Les propriétés d'entrée sont renseignées avant que ngOnInit() soit appelé. Toutefois, cela suppose que la propriété parent qui alimente la propriété d'entrée est déjà renseignée lors de la création du composant enfant.

Dans votre scénario, ce n'est pas le cas - les données d'images sont remplies de manière asynchrone à partir d'un service (d'où une requête http). Par conséquent, la propriété d'entrée ne sera pas renseignée lorsque ngOnInit() sera appelé.

Pour résoudre votre problème, lorsque les données sont renvoyées par le serveur, affectez un nouveau tableau à la propriété parent. Implémentez ngOnChanges() dans l'enfant. ngOnChanges() sera appelée lorsque Angular propage la nouvelle valeur du tableau vers l'enfant.

61
Mark Rajcok