반응형
angular Infinite Scroll 페이징 처리
일반적으로 게시판처럼 데이터를 계속 누적해서 보여줘야 할 때, 페이징을 통해 데이터를 나누어 보여줍니다. 보통 페이징은 "이전, 다음, 첫 페이지, 끝 페이지, 1, 2, 3, 4, ..."와 같은 형태로 구성됩니다. 그러나 데이터 양이 많고, 특히 화면이 작은 모바일 환경에서는 이러한 방식이 불편할 수 있습니다.
이 문제를 해결하기 위해, 스크롤 이벤트를 감지하여 자동으로 페이징을 처리하는 방식이 많이 사용됩니다. 사용자가 스크롤을 내릴 때마다 다음 페이지의 데이터를 자동으로 로드하여, 번호를 누르지 않아도 계속해서 데이터를 볼 수 있게 합니다.
다음은 Angular에서 디렉티브(directive)를 사용하여 스크롤 이벤트를 감지하고, 페이징을 자동으로 처리하는 방법입니다.
1. scroll.directive.ts 생성
import { Directive, HostListener, Output, EventEmitter, Input } from '@angular/core';
interface ScrollEvent {
isReachingBottom: boolean;
originalEvent: Event;
isWindowEvent: boolean;
}
@Directive({
selector: '[appScroll]'
})
export class AppScrollDirective {
@Input() bottomOffset = 100; // 하단에서 얼마나 떨어졌을 때 이벤트를 발생시킬지 설정
@Output() onScroll = new EventEmitter<ScrollEvent>();
// 스크롤 이벤트 핸들러
@HostListener('scroll', ['$event'])
@HostListener('window:scroll', ['$event'])
public handleScroll(event: Event): void {
if (event.target === document || event.target === window) {
this.windowScrollEvent(event);
} else {
this.elementScrollEvent(event);
}
}
// 윈도우 스크롤 처리
// 브라우저 전체 창에 대해 스크롤을 감지하여 전체 페이지를 스크롤할 때 사용
private windowScrollEvent(event: Event): void {
const scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
const isReachingBottom = (document.documentElement.offsetHeight - (window.innerHeight + scrollTop)) < this.bottomOffset;
const emitValue: ScrollEvent = { isReachingBottom, originalEvent: event, isWindowEvent: true };
this.onScroll.emit(emitValue);
}
// 호스트 요소 스크롤 처리
// 특정 요소에 대해 스크롤을 감지하여 특정 영역에서만 스크롤이 발생하는 경우 사용
private elementScrollEvent(event: Event): void {
const target = event.target as HTMLElement;
const scrollPosition = target.scrollHeight - target.scrollTop;
const offsetHeight = target.offsetHeight;
const isReachingBottom = (scrollPosition - offsetHeight) < this.bottomOffset;
const emitValue: ScrollEvent = { isReachingBottom, originalEvent: event, isWindowEvent: false };
this.onScroll.emit(emitValue);
}
}
2. list.component.ts 생성 ( scroll.directive.ts 사용하는 컴포넌트)
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-list',
templateUrl: './list.component.html',
styleUrls: ['./list.component.css']
})
export class ListComponent implements OnInit {
items: number[] = [];
page = 0;
ngOnInit(): void {
this.loadMore();
}
loadMore(): void {
this.page++;
const newItems = Array.from({ length: 20 }, (_, i) => i + this.items.length);
this.items.push(...newItems);
}
onScroll(event: { isReachingBottom: boolean; originalEvent: Event; isWindowEvent: boolean }): void {
if (event.isReachingBottom) {
this.loadMore();
}
}
}
3. list.component.html (템플릿 생성)
<div class="item-list" appScroll (onScroll)="onScroll($event)">
<div class="item" *ngFor="let item of items">
Item {{ item }}
</div>
</div>
4. list.component.css(css 생성)
.item-list {
height: 80vh;
overflow: auto;
}
.item {
padding: 16px;
border-bottom: 1px solid #ccc;
}
반응형
'개발 > front-end' 카테고리의 다른 글
Next.js 를 사용하기 위한 이해(13버전 기준) (2) | 2024.07.24 |
---|---|
Angular에서 뒤로가기 시 스크롤 위치 복원 (0) | 2024.07.17 |
Angular rxjs 비동기 처리 예제 (0) | 2024.07.05 |
angular 라이브러리 만들기 (0) | 2024.07.05 |
angualar CryptoJS 를 이용한 api 통신 예제 (0) | 2024.07.05 |