Bootstrap angular 路由返回时轮播不自动滑动?

Bootstrap Carousel does not auto-slide when routing back in angular?

问题是当我启动我的 angular 应用程序时,使用 bootstrap 旋转木马的图像滑块工作正常。但是当我路由到另一个视图并返回到图像滑块视图时,它不是自动滑动的,而且我可以使用下一个和上一个按钮来更改图像,但它不是自动滑动的。它仅在我重新加载页面时有效。如何解决这个问题?

这是我的代码

.html 文件


    <div id="myCarousel" class="carousel slide carousel-fade" data-bs-ride="carousel" data-bs-pause="false">
    
      <!-- CAROUSEL INDICATORS -->
      <div class="carousel-indicators">
        <div *ngFor="let image of images;index as i;first as isFirst" [class.active]="isFirst">
          <button type="button" data-bs-target="#myCarousel" [attr.data-bs-slide-to]="i" aria-current="true">
          </button>
        </div>
      </div>
      
      <!-- CAROUSEL IMAGES -->
      <div class="carousel-inner">
        <div class="carousel-item active" data-bs-interval="2000" *ngFor="let image of images;first as isFirst" [class.active]="isFirst">
          <img id="carouselImage" src="{{image}}" class="d-block w-100" height="707vh" alt="">
          <div class="carousel-caption d-none d-md-block">
            <h3>It Differentiates Your Brand From Others</h3>
            <p>Kajah Industrial is The leading Industrial In The Country.</p>
            <button class="btn" (click)="btnService()">Watch Our Services</button>
          </div>
        </div>
      </div>
    
      <!-- NEXT AND PREV BUTTON -->
      <button class="carousel-control-prev" type="button" data-bs-target="#myCarousel"  data-bs-slide="prev">
        <span class="carousel-control-prev-icon" aria-hidden="true"></span>
        <span class="visually-hidden">Previous</span>
      </button>
      <button class="carousel-control-next" type="button" data-bs-target="#myCarousel"  data-bs-slide="next">
        <span class="carousel-control-next-icon" aria-hidden="true"></span>
        <span class="visually-hidden">Next</span>
      </button>
    </div>

.ts 文件

import { bootstrap } from 'bootstrap';
...
 ngOnInit() {
    var myCarousel = document.querySelector('#myCarousel')
    var carousel = new bootstrap.Carousel(myCarousel)
  }

angular.json 文件

 "styles": [
              "node_modules/bootstrap/dist/css/bootstrap.min.css",
              "node_modules/font-awesome/css/font-awesome.min.css",
              "./node_modules/aos/dist/aos.css",
              "src/styles.css"
            ],
 "scripts": ["./node_modules/jquery/dist/jquery.min.js",
             "./node_modules/popper.js/dist/umd/popper.min.js",
             "./node_modules/bootstrap/dist/js/bootstrap.min.js",
             "./node_modules/aos/dist/aos.js"
            ]

而且我在控制台中也发现了这个错误

*错误类型错误:无法读取 HomeComponent.ngOnInit 处未定义的 属性 'Carousel' *

有几件事需要考虑。您可以在 .ts 文件中的 import 语句下添加 declare var $: any;。这将允许您访问 Angular 中的 jQuery,它被 bootstrap 轮播使用。

您不应尝试在 ngOnInit 方法中初始化轮播,而应使用 ngAfterContentInitngOnInit 在视图呈现之前触发,因此您的查询选择器找不到该组件,因为 Angular 尚未将其添加到 DOM。

你可以read here about Angular lifecycle hooks.

ngAfterContentInit

Respond after Angular projects external content into the component's view, or into the view that a directive is in.

ngAfterContentInit() {
  const myCarousel = document.querySelector('#myCarousel');
  const carousel = $(myCarousel).carousel();
}

您还应该使用 ViewChild 来引用控件,而不是使用 document.querySelector 作为 Angular 访问 DOM 元素的首选方式。

declare var $: any;

ViewChild('carousel', { static: false }) private _carousel: ElementRef;

ngAfterContentInit() {
   const myCarousel = this._carousel.nativeElement;
   const carousel = $(myCarousel).carousel();
}

在你的 html 添加 #carousel

<div #carousel id="myCarousel" class="carousel slide carousel-fade" 

我通过定义一个隐藏的控制元素修复了这个错误:

 <div class="invisible">
    <ol>
      <li #carousel data-target="#slider" data-slide="next"></li>
    </ol>
 </div>

在上面的代码中,data-target 引用了 bootstrap carosel 组件的 id:

<div id="slider" class="carousel slide" data-ride="carousel"> 
</div>

使用 ViewChild 访问#carousel 模板变量:

 @ViewChild('carousel') carousel: ElementRef;

在 ngAfterViewInit 调用中点击控制元素:

 ngAfterViewInit(): void {
    setInterval(() => {
      this.carousel.nativeElement.click();
    }, 5000)
  }