如何隐藏第一项上的上一个箭头、最后一项上的下一个箭头以及单个项目的两个箭头:基于 angular 的项目;没有jquery?
How to hide prev arrow on first item, next arrow on last item, and both arrow if single item: angular based project; no jquery?
这是一个我希望实现的模板文件:在第一个项目上隐藏上一个箭头,在最后一个项目上隐藏下一个箭头,如果是单个项目则隐藏两个箭头。我在 angular 12 版本中使用了 bootstrap 轮播。
//html code
<div id="carouselExampleControls" *ngIf="selectedMusic?.type==='image'" class="carousel slide" data-bs-touch="false" data-bs-interval="false" data-bs-wrap=false>
<div class="carousel-inner">
<div class="carousel-item" [ngClass] = "{ active: selectedMusic.src === data, first: first, last: last}" *ngFor="let data of carouselAsset; let first = first; let last = last" >
<img *ngIf="selectedMusic?.type==='image'" [src]="data">
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleControls" 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="#carouselExampleControls" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
模板文件中使用的carouselAsset,是对其他文件的package模块实现过滤后的图片文件集合。
//ts code
// For carouselAsset
this.carouselAsset = this.packageDetails.assets.filter(item=>item.fileType==="Images")[0].files.map(itemUrl=>itemUrl.previewUrl);
Bootstrap’s carousel class exposes two events for hooking into
carousel functionality. Both events have the following additional
properties:
direction: The direction in which the carousel is sliding (either "left" or "right").
relatedTarget: The DOM element that is being slid into place as the active item.
from: The index of the current item
to: The index of the next item
All carousel events are fired at the carousel itself (i.e. at the ). Event type Description slide.bs.carousel Fires
immediately when the slide instance method is invoked.
slid.bs.carousel Fired when the carousel has completed its slide
transition.
var myCarousel = document.getElementById('myCarousel')
myCarousel.addEventListener('slide.bs.carousel', function () {
// do something...
})
我们现在知道轮播何时改变是可以控制的。但是在 Angular 中我们通常不使用 docuemnt.getElementById else 模板引用变量和 Viewchild。此外,使用 fromEvent rxjs 运算符比使用 addEventListener 更好。所以首先我们要为我们的元素提供模板引用变量
<div #carousel id="carouselExampleControls" class="carousel slide"..>
<div class="carousel-inner">
<div #item *ngFor="let carousel of carousels; class="carousel-item">
....
</div>
</div>
</div>
查看两个引用变量carousel
和item
想法是在 ngOnInit 中创建一个 observable 以了解“活动轮播”,因此,在 ngOnInit
@ViewChildren('item') items:QueryList<ElementRef>
@ViewChild('carousel',{static:true}) carousel!:ElementRef
change$:any //<--our observable
ngOnInit(){
//enclosed under a setTimeout to give Angular time to
//give value to "items" and "carousel"
setTimeout(()=>{
this.items.first.nativeElement.classList.add("active")
this.change$=fromEvent(this.carousel.nativeElement,'slide.bs.carousel').pipe(
startWith({to:0}),
map((res:any)=>res.to))
})
}
看到如果我们在我们的.html中写一些像
Actual slider: {{change$|async}}
我们将看看如何从 0 到 imagenes length-1
好吧,我们可以使用它,删除之前的行并将按钮放在 ng-container
下
<ng-container *ngIf="{ item: change$ | async } as actual">
<button
*ngIf="actual.item != 0"
class="carousel-control-prev"
...
>
...
</button>
<button
*ngIf="actual.item < carousels.length - 1"
class="carousel-control-next"
...
>
...
</button>
</ng-container>
(*) 结构 *ngIf="{prop:observable|async} as variable
的使用非常普遍,使得变量得到值 {prop:0}
{prop:1}
... 等等。这使得没有必要使两个订阅可观察对象。
这是一个我希望实现的模板文件:在第一个项目上隐藏上一个箭头,在最后一个项目上隐藏下一个箭头,如果是单个项目则隐藏两个箭头。我在 angular 12 版本中使用了 bootstrap 轮播。
//html code
<div id="carouselExampleControls" *ngIf="selectedMusic?.type==='image'" class="carousel slide" data-bs-touch="false" data-bs-interval="false" data-bs-wrap=false>
<div class="carousel-inner">
<div class="carousel-item" [ngClass] = "{ active: selectedMusic.src === data, first: first, last: last}" *ngFor="let data of carouselAsset; let first = first; let last = last" >
<img *ngIf="selectedMusic?.type==='image'" [src]="data">
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleControls" 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="#carouselExampleControls" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
模板文件中使用的carouselAsset,是对其他文件的package模块实现过滤后的图片文件集合。
//ts code
// For carouselAsset
this.carouselAsset = this.packageDetails.assets.filter(item=>item.fileType==="Images")[0].files.map(itemUrl=>itemUrl.previewUrl);
Bootstrap’s carousel class exposes two events for hooking into carousel functionality. Both events have the following additional properties:
direction: The direction in which the carousel is sliding (either "left" or "right"). relatedTarget: The DOM element that is being slid into place as the active item. from: The index of the current item to: The index of the next item
All carousel events are fired at the carousel itself (i.e. at the ). Event type Description slide.bs.carousel Fires immediately when the slide instance method is invoked. slid.bs.carousel Fired when the carousel has completed its slide transition.
var myCarousel = document.getElementById('myCarousel') myCarousel.addEventListener('slide.bs.carousel', function () { // do something... })
我们现在知道轮播何时改变是可以控制的。但是在 Angular 中我们通常不使用 docuemnt.getElementById else 模板引用变量和 Viewchild。此外,使用 fromEvent rxjs 运算符比使用 addEventListener 更好。所以首先我们要为我们的元素提供模板引用变量
<div #carousel id="carouselExampleControls" class="carousel slide"..>
<div class="carousel-inner">
<div #item *ngFor="let carousel of carousels; class="carousel-item">
....
</div>
</div>
</div>
查看两个引用变量carousel
和item
想法是在 ngOnInit 中创建一个 observable 以了解“活动轮播”,因此,在 ngOnInit
@ViewChildren('item') items:QueryList<ElementRef>
@ViewChild('carousel',{static:true}) carousel!:ElementRef
change$:any //<--our observable
ngOnInit(){
//enclosed under a setTimeout to give Angular time to
//give value to "items" and "carousel"
setTimeout(()=>{
this.items.first.nativeElement.classList.add("active")
this.change$=fromEvent(this.carousel.nativeElement,'slide.bs.carousel').pipe(
startWith({to:0}),
map((res:any)=>res.to))
})
}
看到如果我们在我们的.html中写一些像
Actual slider: {{change$|async}}
我们将看看如何从 0 到 imagenes length-1
好吧,我们可以使用它,删除之前的行并将按钮放在 ng-container
下<ng-container *ngIf="{ item: change$ | async } as actual">
<button
*ngIf="actual.item != 0"
class="carousel-control-prev"
...
>
...
</button>
<button
*ngIf="actual.item < carousels.length - 1"
class="carousel-control-next"
...
>
...
</button>
</ng-container>
(*) 结构 *ngIf="{prop:observable|async} as variable
的使用非常普遍,使得变量得到值 {prop:0}
{prop:1}
... 等等。这使得没有必要使两个订阅可观察对象。