Как нацелиться на элемент внутри ngFor с помощью introjs - PullRequest
0 голосов
/ 17 октября 2018

Мне нужно использовать introjs для просмотра новых функций в приложении angular 6.

Внутри тура некоторые пошаговые целевые элементы в ngFor в дочернем компоненте компонента, с которого я запускаю introjs.Библиотека способна нацеливаться на 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();

Есть ли что-то, что я делаю неправильно?неужели интройс вообще не умеет это делать?есть ли другая библиотека, которая может это сделать?

Заранее спасибо

1 Ответ

0 голосов
/ 17 октября 2018

Секции, сгенерированные циклом *ngFor, могут еще не отображаться в событии AfterViewInit.Чтобы обнаружить наличие этих элементов, вы должны использовать @ViewChildren и следить за событием QueryList.changes.

В шаблоне определить ссылочную переменную шаблона #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();
  }
}
...