Flickity 在我使用 *NgFor

问题描述

我正在尝试在我正在构建的 angular 应用程序中使用 Flickity。这是 link 我也知道 ngx-flickity 但我不想要这个,因为它没有准备好。

以下代码有效

<div class="carousel">
    <div class="carousel-cell">...</div>
    <div class="carousel-cell">...</div>
    <div class="carousel-cell">...</div>
    ...
</div> 

我使用 *NgFor 的那一刻,它停止工作,没有任何错误

<div class="carousel">
    <div class="carousel-cell" *ngFor="let product of products">
        {{ product.name }}
    </div>
</div>

我也试过 prepend 方法,但是没有用。

解决方法

首先,您要起诉 document.querySelector('.carousel'),它将只返回一个元素(第一个),以防您有多个轮播元素,它不适用于其他元素。 其次,您希望在返回数据并呈现数据后实例化 flick。 一个快速的解决方法是使用这个:

  ngOnInit(): void {
  this.dataService.getProducts().subscribe(products => {
      this.products = products;
      setTimeout( () => {
       document.querySelectorAll(".carousel").forEach(c => {
        let flick = new flickity(c,{ cellAlign: "left",contain: true});
        })});
    });
  }

更新:

比使用 setTimeout 更好的解决方案是使用 ChangeDetecrotRef 在收到来自服务器的数据后立即强制显式更改检测(呈现)。

import { ChangeDetectorRef,Component,OnInit } from "@angular/core";
...
  constructor(private dataService: DataService,private cdr: ChangeDetectorRef) {}
  ngOnInit(): void {
  this.dataService.getProducts().subscribe(products => {
      this.products = products;
      this.cdr.detectChanges();
      document.querySelectorAll(".carousel").forEach(c => {
        let flick = new flickity(c,contain: true});
        });
    });
  }

Demo

,

看来您应该在获得数据并初始化模板后初始化 flickity。在您的 stackblits 中将 this.flick = ... 代码移动到 ngAfterViewInit() 钩子修复了问题