Показать больше/показать меньше данных ngFor при нажатии кнопки

У меня возникает проблема при отображении и скрытии данных ngFor. Я хочу показать одну запись по умолчанию, и когда кто-либо нажмет кнопку «Просмотреть больше», будет показана оставшаяся запись. Я не хочу автоматически закрывать предыдущие записи. В настоящее время предыдущее содержимое маршрута будет автоматически закрыто, когда я открою другой маршрут. Кто-нибудь, пожалуйста, помогите мне? Вот файл компонентов.

<div class="itineraryDay" *ngFor="let eventList of eventDailyItineraray; let i = index">
<div class="itineraryDay-header">
    <h5>Day {{i+1}}</h5>
    <p>{{eventList.tourevents[0]?.categoryName}}</p>
</div>
<div class="itineraryDay-detail">
    <div class="itinerary-cards">
        <mat-card class="mycard" *ngFor="let event of eventList.tourevents | slice:0:[selectedIndex === i ? max  : 1 ]; let j = index">
            <div class="day-activity d-flex">
                <div class="activity-img">
                    <img [src]="(event?.eventPic ? firstEventImage(event?.itemId,event?.eventPic):'./assets/media/icons/preview-item.svg')" />
                </div>
                <div class="activity-detail">
                    <div class="activity-detail-inner d-flex justify-content-between align-items-center">
                        <div class="activity-category d-flex">
                            <img src="{{categoryPic}}{{event?.categoryIcon}}" />
                            <span>{{event?.itemName}}</span>
                        </div>
                        <div class="activity-hours d-flex align-items-center justify-content-end">
                            <img src="./assets/media/icons/access_time-24px.svg" />
                            <span>{{durationCalculation(event?.duration)}} Hours</span>
                        </div>
                    </div>
                    <p>{{event?.description}}</p>
                </div>
            </div>
        </mat-card>
    </div>
    <div class="see-more">
        <div class="icon-inner">
            <p (click)="toggle(i, $event)" class="seeMore">See More</p>
            <div class="more-icon" (click)="toggle(i, $event)" [ngClass]="{'active': selectedIndex === i}" >
                <i class="flaticon-eye"></i>
            </div>
        </div>
    </div>
</div>

Вот функция щелчка в файле ts.

toggle(index, event){

this.max = this.eventDailyItineraray[index].tourevents.length;

if(this.selectedIndex === index){
  this.selectedIndex = -1;
  event.currentTarget.parentElement.children[0].innerText = 'See More';
}else{
  this.selectedIndex = index;
  event.currentTarget.parentElement.children[0].innerText = 'See Less';
} } 

Скриншот


person Faizi    schedule 08.10.2020    source источник


Ответы (3)


вы хотите управлять списком элементов, поэтому вам нужен массив, а не одна переменная. Так определил массив

more:boolean[]=[]

кроме того, чтобы изменить текст в html, НЕ используйте что-то настолько странное, как event.currentTarget.parentElement.children[0].innerText = 'See More', лучше угловой способ

<p (click)="more[i]==!more[i]" class="seeMore">
    {{more[i]?'See Less':'See more'}}
</p>

И замените свой

`selectedIndex === i` by `more[i]`
person Eliseo    schedule 09.10.2020
comment
Спасибо за вашу помощь! Я хочу также изменить значение фрагмента массива (список элементов) при нажатии кнопки «Подробнее». По умолчанию значение среза равно 0, и при нажатии кнопки «Подробнее» нам нужно показать оставшиеся списки. @Элизео - person Faizi; 12.10.2020

Вы можете попробовать использовать концепцию «trackby» здесь. Он будет отслеживать предыдущие изменения, а другие изменения будут добавляться плавно.

<...*ngFor="let item of items; trackBy:trackByIdentity">

и внутри вашего .ts файла

trackByIdentity(index, item){
     return item.<attribute_which_is_unique>; 
  }
person PushpikaWan    schedule 08.10.2020

Что я делаю в таких случаях (и это может быть дешевое решение, но пока я не мог придумать лучших идей), так это добавляю значение в каждый объект внутри вашего итерируемого объекта, указывая, должен ли этот элемент иметь активный класс или нет. В вашем случае, когда вы получаете youeventList.tourevents, вы можете сопоставить его и добавить что-то вроде (isActive = false) к каждому объекту внутри, а затем привязать это значение к классу каждого элемента в вашем цикле ngFor.

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

person IamFlok    schedule 08.10.2020
comment
Если мы используем этот подход, добавляя/удаляя класс, это повлияет на скорость страницы. если данные большие. @IamFlok - person Faizi; 08.10.2020
comment
В случае огромных данных, разве вы не должны оптимизировать производительность, используя inifnite-scroll или что-то подобное? Я также задаюсь вопросом, есть ли лучшие способы сделать это. @Файзи - person IamFlok; 08.10.2020
comment
Вы использовали подход trackBy раньше? Я не могу добиться этого с помощью трека. Автор @IamFlok. - person Faizi; 08.10.2020
comment
В случае больших объемов данных к каждой записи добавляются изображения, что увеличивает время загрузки страницы. @IamFlok - person Faizi; 09.10.2020
comment
Не могли бы вы прислать мне какой-нибудь пример кода, о котором вы говорили? @IamFlok - person Faizi; 09.10.2020