#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