Javascript 为什么物化css和*NGS的旋转木马不能动态地协同工作来获取图像

Javascript 为什么物化css和*NGS的旋转木马不能动态地协同工作来获取图像,javascript,angular,typescript,angular-material,materialize,Javascript,Angular,Typescript,Angular Material,Materialize,我正试图具体化旋转木马的角度代码。旋转木马与动态数组相关联,但当我将*ngFor与旋转木马类一起使用时,它不起作用 我尝试在for循环中编写class=carousel项,但控制台显示: 无法读取未定义的属性“clientWidth” 此代码不起作用: 模板: 组成部分: 选项={fullWidth:false}; 构造函数私有http:HttpClient{ } 恩戈尼特{ var elems=document.queryselectoral.carousel; var instances=M

我正试图具体化旋转木马的角度代码。旋转木马与动态数组相关联,但当我将*ngFor与旋转木马类一起使用时,它不起作用

我尝试在for循环中编写class=carousel项,但控制台显示:

无法读取未定义的属性“clientWidth”

此代码不起作用:

模板:

组成部分:

选项={fullWidth:false}; 构造函数私有http:HttpClient{ } 恩戈尼特{ var elems=document.queryselectoral.carousel; var instances=M.Carousel.initelems,this.options; } 我只得到了一个图像,它被剪成了两半,好像我去掉了for循环,然后一个接一个地写,就像:


这样做,我可以使旋转木马正常工作,但它没有绑定到我想要的动态数组。

使用AfterViewInit生命周期挂钩,而不是在OnInit中初始化旋转木马

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>
<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>
编辑2

我刚刚意识到有一个更好的方法:在向DOM添加最后一项之后,让*ngFor触发init,而不是在旋转木马初始化时设置超时。为此,请按如下方式更改html:

<div class="carousel">
    <a class="carousel-item" href="#{{hrefs[i]}}!" *ngFor="let item of items;let i = index">
        <img src={{item}}/>
    </a>
</div>
<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"]);
  }
}

已调整。

使用AfterViewInit生命周期挂钩,而不是在OnInit中初始化转盘

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>
<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>
编辑2

我刚刚意识到有一个更好的方法:在向DOM添加最后一项之后,让*ngFor触发init,而不是在旋转木马初始化时设置超时。为此,请按如下方式更改html:

<div class="carousel">
    <a class="carousel-item" href="#{{hrefs[i]}}!" *ngFor="let item of items;let i = index">
        <img src={{item}}/>
    </a>
</div>
<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"]);
  }
}

已调整。

您应该尝试使动态模板与预期的静态结果相匹配。您可以这样做:您应该尝试使您的动态模板与预期的静态结果相匹配。您可以试试这个:您好,谢谢您的回复,我正在使用items数组,它使用subscribe从api获取数据,它在ngOnInit中。您的代码可以工作,但我仍然得到相同的错误,客户端宽度未定义。我尝试在模板上使用带if条件的布尔检查showCarousel,然后Carosel不会出现,但也没有显示错误this.getItems.subscriberes=>{this.response=res;this.response.forEachentry=>{if entry.url&&entry.description{this.items.0,0,entry.url;this.showCarousel=true;}@SurajSharma请检查我编辑的答案现在是否解决了您的问题。@SurajSharma我有另一个想法,请检查我修改的答案。我尝试了您的两种代码,第二种代码在加载数据的主题下工作得很好,第三种变体显示图像,但我无法滑动/移动旋转木马。第二种变体可以我想被标记为解决方案。再次感谢@coreuter:@SurajSharma我已经修复了第三个变体。它需要设置超时,还需要检查最后一个Stackblitz。您必须自己单击答案左侧的复选标记。您好,感谢您的回复,我正在使用items数组,它使用subscribe从api获取数据,并且在ngOnI内部nit..您的代码正常工作,但我仍然收到相同的错误客户端宽度未定义。我尝试在模板上使用带if条件的布尔检查showCarousel,然后Carosel不会出现,但也没有显示错误。this.getItems.subscriberes=>{this.response=res;this.response.forEachentry=>{if entry.url&&entry.description{this.items.0,0,entry.url;this.showCarousel=true;}@SurajSharma请检查我编辑的答案现在是否解决了您的问题。@SurajSharma我有另一个想法,请检查我修改的答案。我尝试了您的两种代码,第二种代码在加载数据的主题下工作得很好,第三种变体显示图像,但我无法滑动/移动旋转木马。第二种变体可以我认为这是一个解决方案。再次感谢@coreuter:@SurajSharma我已经修复了第三个变体。它需要设置超时以及检查最后一次Stackblitz。您必须单击答案左侧的复选标记来检查自己。