因此,在我当前的项目中,我正在尝试创建一个产品滑块。为了正确工作,我需要得到所有产品的宽度,这样我就可以计算出总宽度。目前我正在做的是
ngAfterViewInit(): void {
this.service.getData().subscribe((items) => {
for (let key in items) {
this.items.push(items[key]);
}
this.cd.detectChanges();
this.cards = this.elem.nativeElement.querySelectorAll('.card');
console.log(this.cards); // In this log i am getting all the cards have the correct width
this.cards.forEach((card) => {
console.log(card.getBoundingClientRect());//But in this log widths are different
this.totalWidth += card.clientWidth;
});
console.log(this.totalWidth);
});
}
在ngAfterViewInit中,在调用我的后端并将其设置为laocal变量后,我手动运行更改检测。之后,如果我是控制台日志记录,我将获得所有项目都具有正确宽度的节点列表。但是,如果我试图在节点列表上循环以获得totalwidth,我会得到不同的值。在每张卡片中,我目前显示的是一张图片和一条文字。我没有将卡片的宽度设置为固定值,我将图像的高度设置为固定的值,应用与该高度相对应的宽度,以便图像能够响应。因此,我在节点列表上的循环给了我错误的宽度值,直到图像从内存缓存加载为止。因此,我的猜测是加载图像需要一定的时间,而我的卡的宽度取决于图像的宽度,这就是为什么如果我试图在节点列表上循环,我会得到错误的宽度值。但是,为什么节点列表中的宽度值是正确的,以及如果我试图循环遍历它们,为什么会发生变化?我应该如何解决这个问题,在不使用setTimeOut()
的情况下加载组件后,立即根据每个卡的宽度获得总宽度。
这里是演示stackblitz代码-https://stackblitz.com/edit/angular-ivy-czs5mo?file=src/app/app.component.ts
您需要在您的图像中检查事件(load)
。有些像
<img src="https://picsum.photos/200/300" (load)="onLoad()"/>
count:number=0;
yet:boolean=false;
onLoad()
{
count++;
this.checkWidth()
}
ngAfterViewInit()
{
this.yet=true;
this.checkWidth()
}
this.checkWidth()
{
if (this.yet && count==imagesLength)
{
..do something..
}
}
注意:请改用
//I don't like so much
this.elem.nativeElement.querySelectorAll('.card');
您可以在.html中使用referenceVariable#card
,并使用ViewChildren 控制元素
@ViewChildren('card') cards:QueryList<ElementRef>
并使用
this.cards.forEach(x=>{
const rect=x.nativeElement.getBoundingClientRect()
console.log(rect)
...
})