Ich habe eine Komponente, die ein Array von image
Objekten als Input
Daten empfängt .
export class ImageGalleryComponent {
@Input() images: Image[];
selectedImage: Image;
}
Ich möchte, wenn die Komponente den selectedImage
Wert lädt , auf das erste Objekt des images
Arrays gesetzt werden. Ich habe versucht, dies im OnInit
Lebenszyklus-Hook wie folgt zu tun :
export class ImageGalleryComponent implements OnInit {
@Input() images: Image[];
selectedImage: Image;
ngOnInit() {
this.selectedImage = this.images[0];
}
}
Dies gibt mir einen Fehler, Cannot read property '0' of undefined
was bedeutet, dass der images
Wert auf dieser Stufe nicht eingestellt ist. Ich habe auch den OnChanges
Hook ausprobiert , stecke aber fest, weil ich keine Informationen darüber erhalten kann, wie Änderungen eines Arrays beobachtet werden können. Wie kann ich das erwartete Ergebnis erzielen?
Die übergeordnete Komponente sieht folgendermaßen aus:
@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
);
}
}
Die Vorlage der übergeordneten Komponente enthält dies
...
<image-gallery [images]="images"></image-gallery>
...
javascript
angular
typescript
Optimus Pette
quelle
quelle
images
Daten in der übergeordneten Komponente ausgefüllt? Dh, ist es über eine http-Anfrage (n)? In diesem Fall ist es möglicherweise besser, wenn die ImageGalleryComponent das http-Observable abonniert ().images
sind nur ein Teil der Daten, die vom Elternteil wie folgt verwendet werden.{profile: {firstName: "abc", lastName: "xyz", images: [ ... ]}}
Wenn ich das Kind abonniere, muss ich mich immer noch für das Elternteil anmelden und ich möchte die Wiederholung vermeidenAntworten:
Eingabeeigenschaften werden ausgefüllt, bevor sie
ngOnInit()
aufgerufen werden. Dies setzt jedoch voraus, dass die übergeordnete Eigenschaft, die die Eingabeeigenschaft speist, bereits beim Erstellen der untergeordneten Komponente ausgefüllt ist.In Ihrem Szenario ist dies nicht der Fall - die Bilddaten werden asynchron von einem Dienst ausgefüllt (daher eine http-Anforderung). Daher wird die Eingabeeigenschaft beim
ngOnInit()
Aufruf nicht ausgefüllt .Um Ihr Problem zu lösen, weisen Sie der übergeordneten Eigenschaft ein neues Array zu, wenn die Daten vom Server zurückgegeben werden.
ngOnChanges()
Im Kind implementieren .ngOnChanges()
wird aufgerufen, wenn die Winkeländerungserkennung den neuen Array-Wert an das untergeordnete Element weitergibt.quelle
ngOnchanges()
das Kind implementiert habe , kommt der FehlerCannot read property '0' of undefined
. Die App kann jedoch problemlos fortgesetzt werden. Dieser Fehler tritt auf, weil die Eingabeeigenschaft anfangs nicht ausgefüllt wurde. Es wird beim zweiten AufrufngOnChanges()
ausgefüllt, wenn die Daten vom asynchronen Aufruf empfangen werden. Für meinen Fall habe ich zusätzlich zu dieser Lösung den Schutz gegen den Null- Operator im HTML hinzugefügt . Der Fehler wurde eindeutig behoben.Sie können auch einen Setter für Ihre Bilder hinzufügen, der aufgerufen wird, wenn sich der Wert ändert, und Sie können Ihr standardmäßig ausgewähltes Bild im Setter selbst festlegen:
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; }
quelle