如何使用 introjs 定位 ngFor 中的项目

How to target an item inside ngFor with introjs

我需要使用 introjs 来了解 angular 6 应用程序的新功能。

在导览中,在我启动 introjs 的组件的子组件中,ngFor 中的一些步骤目标项目。该库能够以子组件 html 元素为目标,但似乎无法以 ngFor 内部的元素为目标。我想要的用法很简单我有一个 li 代表我循环的卡片项目:

<div *ngFor="let source of sourcesDisplay; let idx = index" class="col-lg-5ths col-md-4 col-sm-6 col-xs-12">
        <!-- item -->
    <div class="item blue-light">
      <div class="header">
        <div class="categories">
          <div class="truncat">{{source.categories.length > 0? source.categories : 'NO CATEGORY'}}</div>
        </div>
        <a routerLink="{{ organization?.name | routes: 'sources' : source.id }}" class="title">
          <div class="truncat">{{source.name}}</div>
        </a>
        <div class="corner-ribbon blue-light" *ngIf="isARecentSource(source.createdAt)">New</div>
        <div class="corner-fav" [class.is-active]="isSourceFavorite(source.id)"
             (click)="toggleFavorite(source.id)"><em class="icon-heart-o"></em></div>
      </div>
      <a class="content" routerLink="{{ organization?.name | routes: 'sources' : source.id }}">
        <div class="icon">
          <em [ngClass]="source.icon? 'icon-'+source.icon : 'icon-cocktail3'"></em>
        </div>
      </a>
      <div class="actions">
        <ul class="buttons three">
          <li class="icon-font" ><a (click)="openDashboardModal(source)"
                                   [class.disable]="source.powerbi.length === 0" class="btn-effect"><em
            class="icon-chart-bar"></em></a></li>
          <li class="icon-font"><a
            (click)="openDatalakeModal(source)" [class.disable]="source.datalakePath.length === 0"
            class="btn-effect"><em class="icon-arrow-to-bottom"></em></a>
          </li>
          <li class="icon-font"><a routerLink="{{ organization?.name | routes: 'sources' : source.id }}"
                                   class="btn-effect"><em class="icon-info-circle"></em></a></li>
        </ul>
      </div>
    </div>
  </div><!-- /item -->

我想像按钮一样定位这张卡片的一部分,例如:

<li class="icon-font" id="step4{{idx}}">
   <a (click)="openDashboardModal(source)" [class.disable]="source.powerbi.length === 0" class="btn-effect">
     <em class="icon-chart-bar"></em>
   </a>
</li>

然后在我的组件中:

const intro = IntroJs.introJs();
intro.setOptions({
  steps: [
    {
      element: document.querySelector('#step40'),
      intro: 'Welcome to the Data Portal ! Explore and download data accross any division. Let\'s discover the new home page.'
    }]})
intro.start();

我做错了什么吗? introjs 根本做不到吗?是否有另一个库可以做到这一点?

提前致谢

*ngFor 循环生成的部分可能尚未在 AfterViewInit 事件中呈现。要检测这些元素的存在,您应该使用 @ViewChildren 并监视 QueryList.changes 事件。

在模板中,定义一个 template reference variable #step 而不是 id:

<li class="icon-font" #step>
   <a (click)="openDashboardModal(source)" [class.disable]="source.powerbi.length === 0" class="btn-effect">
     <em class="icon-chart-bar"></em>
   </a>
</li>

在代码中,获取带有@ViewChildren的元素,并订阅QueryList.changes事件。您可能必须将 QueryList 转换为数组才能访问具有特定索引的元素。

@ViewChildren("step") steps: QueryList<ElementRef>;

ngAfterViewInit() {
  this.startIntroJs(); // Maybe already present
  this.steps.changes.subscribe((list: QueryList<ElementRef>) => {
    this.startIntroJs(); // Created later
  });
}

private startIntroJs(): void {
  if (this.steps.length > 40) {
    const intro = IntroJs.introJs();
    intro.setOptions({
      steps: [
        {
          element: this.steps.toArray()[40].nativeElement,
          intro: 'Welcome to the Data Portal...'
        }
      ]
    });
    intro.start();
  }
}