作为个人挑战,我正在尝试创建一个网站,在该网站中您可以看到英雄联盟冠军名单,然后单击他们的图标以获取更多详细信息。
但是,我的冠军的详细信息(特别是图片)似乎延迟了一秒钟。
在这里,我点击了Kaisa
的图片,但是上一个冠军的图片正在显示
这是我获取数据的方式。
家长TS
export class ChampionListComponent implements OnInit {
public displayPopup = false;
public selectedChamp: Observable<any>;
constructor(private store: Store<LolState>) { }
ngOnInit() {
this.selectedChamp = this.store.pipe(select(selectChampDetails));
}
selectChamp(name) {
this.displayPopup = true;
this.store.dispatch(new GetChampionsDetails(name));
}
PARENT HTML
<ul class="champion_list">
<li (click)="selectChamp(champion.key)">
...List of champions
</li>
</ul>
<ng-container *ngIf="displayPopup">
<app-champion-details *ngIf="selectedChamp | async as champ" [selectedChamp]="champ"></app-champion-details>
</ng-container>
儿童TS
export class ChampionDetailsComponent implements OnInit {
@Input() selectedChamp: any;
public skins: Array<{path: string}>;
constructor() { }
ngOnInit(): void {
if (this.selectedChamp.skins) {
this.skins = this.selectedChamp.skins.map(skin => {
return {path: 'LINK'}
})
}
}
儿童HTML
<section *ngIf="selectedChamp as Champ" class="container">
<carousel cellWidth="100%" cellToShow="1" [loop]="true" [images]="skins"></carousel>
<div class="champ_infos">
<h2>{{Champ.id | titlecase}}</h2>
<h3>{{Champ.title | titlecase}}</h3>
<article>
{{Champ.lore}}
</article>
</div>
</section>
我从服务中获取信息,其中一个效果调用了该效果,该操作调度操作并以我的状态存储数据。信息以我的状态很好地存储,如果我尝试在父级中使用console.log selectChamp
,它将显示良好的信息,在这里没有问题。
似乎Angular在输入接收到信息之前试图执行map
吗?
编辑:我在孩子中将*ngIf="selectedChamp as Champ"
替换为*ngIf="skins"
,因此除非全部加载,否则内容不会显示,您可以在gif中看到结果。
(我删除了一些与问题无关的代码,如果存在一些错别字/未知变量,请忽略它,因为这不是问题的根源)
答案 0 :(得分:1)
将输入用于子组件时,该值在OnChanges生命周期中可用。 因此,您可以尝试以下方法:
ngOnChanges(changes: SimpleChanges) {
if(changes && this.selectedChamp && this.selectedChamp.skins){
this.skins = this.selectedChamp.skins.map(skin => {
return {path: 'LINK'}
})
}
}
在此生命周期中,每次在父级中更新值时,您都可以在子级中获取它。
答案 1 :(得分:1)
问题是这样的:
<ng-container *ngIf="displayPopup">
<app-champion-details *ngIf="selectedChamp | async as champ" [selectedChamp]="champ"></app-champion-details>
</ng-container>
当displayPopup
变为true时,您已经在显示champion-details
,因为selectedChamp
的Observable已经具有一个值,如果这是您第二次打开详细信息组件,则该值已经出现。新值将在稍后的时间异步到达,但是组件已经初始化,因此子组件的ngOnInit
已实现,并且显示旧状态。
我建议您采取一些不同的方法。关闭明细组件时,请清除商店中的selectedChamp
。这样一来,您甚至都不需要ng-container
,而只需依靠*ngIf="selectedChamp | async as champ"
来显示详细信息部分。
<app-champion-details *ngIf="selectedChamp | async as champ" [selectedChamp]="champ"></app-champion-details>
因此,您可以在closeChampionDetails
方法中执行以下操作:
public closeChampionDetails() {
this.store.dispatch(new ClearSelectedChampion());
}
答案 2 :(得分:0)
在子组件中,必须防止在将输入selectedChamp
传递给数据之前调用它,以便您可以执行类似的操作
ngOnInit(): void {
if (this.selectedChamp && this.selectedChamp.skins) {
this.skins = this.selectedChamp.skins.map(skin => {
return {path: 'LINK'}
})
}
}