如何按角度计算DOM中的li元素?

问题描述

问题:如何计算DOM中显示 li 元素的当前数量

    <ul *ngFor="let l of givenList.slice(0,showmorenumbers); let i= index">
      <li>{{l}}</li>
    </ul>

<button (click)="showmore()"> show more</button>
<button (click)="showless()"> showLess</button>

解决方法

可以通过使用普通JS获得DOM中li元素的数量。 以下应该做的工作:

document.querySelectorAll('li').length

但是,正如@Muthupriya在评论部分中提到的那样,这可能不是解决问题的最佳方法。

我建议创建其他变量(或使用现有的showmorenumbers)来跟踪显示的项目数(例如numberOfDisplayedItems)。可以用showmore方法递增。

如果numberOfDisplayedItems === givenList.length,则应该隐藏显示更多按钮。另外,numberOfDisplayedItems绝对不能大于givenList.length,因此在增加numberOfDisplayedItems时要记住这一点。

,

对于性能,当列表变大时,在HTML上执行功能(即行givenList.slice(0,showmorenumbers))并不理想。 DOM中的任何更改都会导致调用此函数,并且可能导致应用程序性能下降。

请考虑为您使用observables。根据您的情况的示例,可以按以下方式处理

在TS文件中

导入必要的导入,请确保从combineLatest导入rxjs而不是rxjs/operators

import { map } from 'rxjs/operators';
import { combineLatest,Observable,of,BehaviorSubject } from 'rxjs';

声明可观察者

givenList$: Observable<string[]> = of([
  'Item 1','Item 2','Item 3','Item 4','Item 4'
]);

声明要显示为BehaviorSubjects的物品的增量,最小和最大数量

incrementSubject$ = new BehaviorSubject<number>(5);
incrementAction$ = this.incrementSubject$.asObservable();
minQuantitySubject$ = new BehaviorSubject<number>(5);
minQuantityAction$ = this.minQuantitySubject$.asObservable();
maxQuantitySubject$ = new BehaviorSubject<number>(20);
maxQuantityAction$ = this.maxQuantitySubject$.asObservable();
currentQuantity = this.minQuantitySubject$.value;

声明一个可观察值以跟踪当前数量

currentQuantity$ = combineLatest([
  this.incrementAction$,this.minQuantityAction$,this.maxQuantityAction$ ]).pipe(
    map(([increment,minQuantity,maxQuantity]) => {
      this.currentQuantity = Math.min(
        Math.max(minQuantity,this.currentQuantity + increment),maxQuantity
      )
      return this.currentQuantity
    })
  )

声明过滤列表

filteredList$: Observable<string[]> = combineLatest([
  this.givenList$,this.currentQuantity$]).pipe(
    map(([givenList,quantity]) => givenList.slice(0,quantity))
  )

在您的HTML中

您现在可以使用async管道进行订阅。这样,我们就不必取消订阅以避免内存泄漏,因为angular会为我们做到这一点

<ul *ngFor="let l of filteredList$ | async; let i= index">
  <li>{{ i }} : {{l}}</li>
</ul>

现在要更改参数,我们只需要调用incrementSubject$中的下一个函数,并传递一个值incrementSubject$.next(5),这将触发更改检测,从而使DOM重新评估

<button (click)='incrementSubject$.next(5)'>Increment 5</button>
<button (click)='incrementSubject$.next(-5)'>Reduce 5</button>
<button (click)='minQuantitySubject$.next(3)'>Make Min 3</button>
<button (click)='minQuantitySubject$.next(5)'>Make Min 5</button>

通过这种反应式编程,我们甚至可以使用changeDetection: ChangeDetectionStrategy.OnPush来进一步提高应用性能

请参见Example here on stackblitz