gpt4 book ai didi

javascript - 为什么物化 css 的轮播和 *ngFor 不能动态地协同工作来获取图像

转载 作者:行者123 更新时间:2023-11-30 14:04:43 25 4
gpt4 key购买 nike

我正在尝试实现轮播的 Angular 代码。轮播与动态数组相关联,但是当我使用 *ngFor 时对于轮播类,它不起作用。

我试着写 class="carousel-item"在 for 循环内,但控制台显示:

Cannot read property 'clientWidth' of undefined.

此代码无效:

模板:

<div class="carousel carousel-slider">
<div class="carousel-item" href="#one!">
<div *ngFor ="let item of items;let i = index">
<img src={{items[i]}}>
</div>
</div>
</div>

组件:

options = {fullWidth: false};

constructor(private http: HttpClient) {
}

ngOnInit() {
var elems = document.querySelectorAll('.carousel');
var instances = M.Carousel.init(elems, this.options);
}

我也只得到一张图像,它被裁剪成两半,就好像我删除了 for 循环并写了 <div class="carousel-item">一个接一个喜欢:

<a class="carousel-item" href="#one!"><img src={{items[0]}}></a>
<a class="carousel-item" href="#two!"><img src={{items[1]}}></a>
<a class="carousel-item" href="#three!"><img src={{items[2]}}></a>

这样做,我让轮播工作,但它没有绑定(bind)到我想要的动态数组。

最佳答案

不要在 OnInit 中初始化轮播,而是使用 AfterViewInit 生命周期钩子(Hook)

import { Component, OnInit, AfterViewInit } from '@angular/core';
// other imports

@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, AfterViewInit {
// ...

constructor(private http: HttpClient) {}

ngOnInit() {}

ngAfterViewInit() {
var elems = document.querySelectorAll('.carousel');
var instances = M.Carousel.init(elems, this.options);
}
}

另外像这样改变你的模板:

<div class="carousel">
<a class="carousel-item" href="#{{hrefs[i]}}!" *ngFor="let item of items;let i = index">
<img src={{item}}/>
</a>
</div>
a-tag 上的

*ngFor 将创建 materialize 所需的结构。

使用当前元素的索引和一个名为“hrefs”的新数组,为每个 a-tag 单独设置 href 属性。

请查看此 Stackblitz一个工作示例。

编辑:使用 API 响应

错误“无法读取未定义的属性‘clientWidth’”现在出现(以及在 OnInit 中轮播初始化期间),因为当时 M.Carousel.init (...) 被称为 HTML 结构还不完整。只要 this.items 未定义,就没有类 carousel-item 的 a-tags。

要解决此问题,必须延迟实体化轮播的初始化,直到从服务器加载数据并且所有 a-tag 都已通过 *ngFor 添加到 DOM。

// removed code because it wasn't the best solution..
// it's still in the Stackblitz as comment

编辑 #2

我刚刚意识到有一个更好的方法:不是在轮播初始化时设置超时,而是让 *ngFor 在将最后一项添加到 DOM 后触发初始化。为此,请像这样更改您的 html:

<div class="carousel">
<a class="carousel-item" href="#{{hrefs[i]}}!" *ngFor="let item of items;let i = index; let last = last">
<img src={{item}}/>
<ng-container *ngIf="last">{{initCarousel()}}</ng-container>
</a>
</div>

在您的组件中,您现在只需要以下内容:

// imports
// ...

export class AppComponent implements OnInit {
// ...

ngOnInit() {
// dummy api request
this.fakeApiRequest().pipe(delay(2000)).subscribe((res) => {
// parse api response
this.items = res;
});
}

initCarousel() {
// timeout needed, otherwise navigation won't work.
setTimeout(() => {
let elems = document.querySelectorAll('.carousel');
let instances = M.Carousel.init(elems, this.options);
}, 100);
}

fakeApiRequest(): Observable<string[]> {
return of(["https://picsum.photos/200/300?image=0", "https://picsum.photos/200/300?image=1", "https://picsum.photos/200/300?image=2", "https://picsum.photos/200/300?image=3", "https://picsum.photos/200/300?image=4"]);
}
}

调整后 Stackblitz .

关于javascript - 为什么物化 css 的轮播和 *ngFor 不能动态地协同工作来获取图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55667029/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com