【问题标题】:angular carousel with slide show, reset after clicking on dot button, using rxjs带有幻灯片放映的角轮播,单击点按钮后重置,使用 rxjs
【发布时间】:2021-02-05 10:17:11
【问题描述】:

工作样本在此Stackblitz Link

我正在使用 rxjs 构建角度轮播滑块更改组件。每张幻灯片在 5 秒后更换。目前工作正常。但是我的问题是,当单击dot-button 时,单击的相同点幻灯片会返回并显示该幻灯片,但下一个更改不是从上一次单击的位置开始,如果单击,则检测我在上面的堆栈闪电战链接中所说的内容看到下一张幻灯片的任何点都不会从单击它的位置开始。我目前在做什么如下所示..

export class AppComponent {
   dotsLength;

   selectedDotIndexSubject = new BehaviorSubject<number>(undefined);
   selectedDotIndexSubject$ = this.selectedDotIndexSubject
   .asObservable()
   .pipe(
         switchMap(index => concat(of(index), of(undefined).pipe(delay(5000))))
    );

   readonly currentIndex$ = range(1, 3).pipe(
      concatMap(value => of(value).pipe(delay(5000))),
      repeat()
   );

   mainSlider$ = combineLatest([
       this.selectedDotIndexSubject$,
       this.currentIndex$
   ]).pipe(
          map(([selectedIndex, autoIndex]) => {
              return selectedIndex ?? autoIndex;
          })
    );
   readonly images = ["6027869", "3889926", "6027869"];
    ngOnInit() {
       this.dotsLength = new Array(this.images.length).fill(0);
    }
    dotClick(index: any) {
       this.selectedDotIndexSubject.next(index);
    }
}

如上代码所示,我正在组合两个rxjs流,一个是点击主题,另一个是range()操作符和repeat()操作符。

这是组件的模板文件

<ng-container *ngIf="mainSlider$ | async as currentIndex">
    <h2>Automatic Slideshow</h2>
       {{currentIndex}}
            <p>Change image every 2 seconds:</p>
        <div class="slideshow-container">
           <div *ngFor="let image of images; let i = index;" class="mySlides fade" [class.active]="i === currentIndex - 1">
           <div class="numbertext">{{ i + 1 }} / {{ images.length }}</div>
        <img
    [src]="'https://images.pexels.com/photos/' + image + '/pexels-photo-' + image + '.jpeg'">
        <div class="text">
            Caption {{ i + 1 }}
        </div>
    </div>
</div>

<br>
<div style="text-align:center">
    <span *ngFor="let dots of dotsLength; let i = index;"
    [class.active]="currentIndex - 1  === i"
    #dot
    (click)="dotClick(i + 1)"
    class="dot">
 </span>
 </div>

 </ng-container> 

【问题讨论】:

    标签: javascript angular rxjs carousel


    【解决方案1】:

    您的计数未恢复的原因是您点击时计数器未重置。所以它会立即使用点击的索引,但随后会返回到下一个。

    在手动单击一个点时重置计数器的最简单方法可能是启动一个以稳定间隔发射的新 observable。

    您可以使用单个 BehaviorSubject 发出单击点的索引,该索引可用于生成一个新的 observable,该 observable 以从该索引值开始的间隔发出。

      selectedIndexSubject = new BehaviorSubject<number>(0);
    
      currentIndex$ = this.selectedIndexSubject.pipe(
        switchMap(selectedIndex => timer(0, 2000).pipe(
          map(tick => (tick + selectedIndex) % this.imageIds.length)
        ))
      );
    
      dotClick(index: number) {
        this.selectedIndexSubject.next(index);
      }
    

    我注意到您在模板中使用基于 1 的索引,而在控制器中使用基于 0 的索引。我发现总是使用从 0 开始更容易。我知道*ngIf 在展开后的值是假的 (0) 时会导致问题,因为它会在索引 = 0 时隐藏您的模板。

    我喜欢使用一种技术很好地克服了这个问题,那就是向您的视图公开一个可观察的对象,该对象包含您的视图所需的所有数据。这样,对象永远不会是虚假的,并且任何恰好是 0 的值都可以轻松访问。

    这是一个有效的StackBlitz

    【讨论】:

    • 关于这个的最后一个问题,我们怎样才能让touchStarttouchMovetouchEnd事件来改变幻灯片。在移动设备中,如果我们 touchOn 当前幻灯片,如果我们向右移动它,那么下一张幻灯片应该进来,如果我们向左移动,上一张幻灯片进来。?
    • stackblitz.com/edit/… 现在我正在做这样的触摸幻灯片更改。但这打破了 pipe() 循环,这是正确的方法吗?在 chrome 开发工具的移动视图中,从左侧或右侧滑动更改。
    • 我查看了您的 SB,但没有发现问题。你是什​​么意思“这打破了 pipe() 循环”?也许这会在一个单独的问题中得到更好的解释。
    猜你喜欢
    • 2022-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多