Javascript Angular:生命周期钩子是组件可用的输入数据
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38020950/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Angular: In which lifecycle hook is input data available to the Component
提问by Optimus Pette
I have a component which receives an array of image
objects as Input
data.
我有一个组件,它接收一组image
对象作为Input
数据。
export class ImageGalleryComponent {
@Input() images: Image[];
selectedImage: Image;
}
I would like when the component loads the selectedImage
value be set to the first object of the images
array. I have tried to do this in the OnInit
lifecycle hook like this:
我想在组件加载时将selectedImage
值设置为images
数组的第一个对象。我试图在OnInit
生命周期钩子中这样做:
export class ImageGalleryComponent implements OnInit {
@Input() images: Image[];
selectedImage: Image;
ngOnInit() {
this.selectedImage = this.images[0];
}
}
this gives me an error Cannot read property '0' of undefined
which means the images
value isn't set on this stage. I have also tried the OnChanges
hook but I'm stuck because i can't get information on how to observe changes of an array. How can I achieve the expected result?
这给了我一个错误Cannot read property '0' of undefined
,这意味着该images
值未在此阶段设置。我也试过这个OnChanges
钩子,但我被卡住了,因为我无法获得有关如何观察数组变化的信息。我怎样才能达到预期的结果?
The parent component looks like this:
父组件如下所示:
@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
);
}
}
The parent component's template has this
父组件的模板有这个
...
<image-gallery [images]="images"></image-gallery>
...
回答by Mark Rajcok
Input properties are populated before ngOnInit()
is called. However, this assumes the parent property that feeds the input property is already populated when the child component is created.
在ngOnInit()
调用之前填充输入属性。但是,这假设在创建子组件时已经填充了提供输入属性的父属性。
In your scenario, this is not the case – the images data is being populated asynchronously from a service (hence an http request). Therefore, the input property will not be populated when ngOnInit()
is called.
在您的场景中,情况并非如此——图像数据是从服务异步填充的(因此是 http 请求)。因此,在ngOnInit()
调用时不会填充输入属性。
To solve your problem, when the data is returned from the server, assign a new array to the parent property. Implement ngOnChanges()
in the child. ngOnChanges()
will be called when Angular change detection propagates the new array value down to the child.
为了解决您的问题,当数据从服务器返回时,为父属性分配一个新数组。ngOnChanges()
在孩子身上实施。 ngOnChanges()
当 Angular 更改检测将新数组值向下传播到子级时将调用。
回答by Sachin Parashar
You can also add a setter for your images which will be called whenever the value changes and you can set your default selected image in the setter itself:
您还可以为您的图像添加一个设置器,每当值更改时都会调用该设置器,您可以在设置器本身中设置默认选择的图像:
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;
}