Как посчитать элементы li в DOM в angular?

#angular #list #count #slice

#angular #Список #подсчитать #срез

Вопрос:

Вопрос: Как я могу посчитать текущее количество отображаемых элементов li в DOM?

     <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>
  

Комментарии:

1. Не могли бы вы, пожалуйста, уточнить свой вопрос? @Laxmee

2. У меня есть две кнопки, как указано выше. Я хочу показать фиксированное количество элементов в списке (скажем, 5), где showmorenumbers = 5 в приведенном выше коде. при нажатии кнопки showmore в список добавляется еще 5 элементов. Моя задача — скрыть кнопку showmore при отображении полного списка (после нажатия showmore пару раз). Для этого я хочу отслеживать, сколько элементов уже отображено в DOM. Я надеюсь, что это имеет смысл. @Muthupriya

3. Для этого вы будете использовать значение индекса и длину вашего массива. Например: скройте свою кнопку showmore, если это условие i == givenList.length-1 удовлетворяет. Я надеюсь, что это поможет вам. @Laxmee

Ответ №1:

Количество элементов li в DOM может быть получено с использованием простого JS. Следующее должно выполнить работу:

 document.querySelectorAll('li').length
  

Однако, как упоминал @Muthupriya в разделе комментариев, это, вероятно, не лучший способ решения вашей проблемы.

Я бы предложил создать дополнительную переменную (или использовать существующую showmorenumbers ) для отслеживания количества отображаемых элементов (скажем numberOfDisplayedItems ).). Он может быть увеличен в showmore методе.

Если numberOfDisplayedItems === givenList.length тогда кнопка показать больше должна быть скрыта. Также numberOfDisplayedItems никогда не должно быть больше givenList.length , поэтому имейте это в виду при увеличении numberOfDisplayedItems .

Ответ №2:

Для повышения производительности, когда список становится больше, было бы не идеально выполнять функции в вашем html, то есть в строке givenList.slice(0,showmorenumbers) . Любое изменение в DOM приведет к вызову этой функции, и это может привести к снижению производительности вашего приложения.

Рассмотрите возможность использования наблюдаемых для вашего. Пример в вашем случае это можно обработать, как показано ниже

В файле 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 для большего повышения производительности приложения

Смотрите пример здесь, на stackblitz