【问题标题】:How to target an item inside ngFor with introjs如何使用 introjs 定位 ngFor 中的项目
【发布时间】:2019-03-22 05:29:43
【问题描述】:

我需要使用 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 被渲染
  • 你是在 ngAfterViewInit() 中开始介绍吗?
  • 这段代码。 const intro = IntroJs.introJs(); intro.setOptions({ steps: [ { element: document.querySelector('#step40'), intro: '欢迎来到数据门户!探索和下载跨部门的数据。让我们发现新的主页。'} ]}) intro.start();
  • 我在 ngOnInit 中启动它,我会在 afterviewinit 上尝试
  • 我是在渲染元素后完成的,但仍然无法正常工作:/

标签: javascript angular angular6 ngfor intro.js


【解决方案1】:

*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();
  }
}

【讨论】:

  • 我尝试了您的解决方案。它不起作用,viewChildren 没有检测到 ngFor 列表上的更改。我的数据在 afterViewInit 上异步加载,列表没有加载,是的,所以还没有渲染。我做了一些研究,似乎 ngFor 上的 viewchildren 没有检测到变化。你知道任何解决方法吗?我不想隐藏我的列表并只为巡演做静态的东西......
  • ViewChildren 是检测由ngForngIf 引起的更改的好方法(请参阅this stackblitz)。如果它不适合您,请提供一个显示问题的 stackblitz。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-01
  • 2020-09-18
  • 2017-06-25
  • 1970-01-01
  • 2017-05-29
  • 2019-03-11
相关资源
最近更新 更多