ฉันจำเป็นต้องใช้การเลื่อนแบบไม่สิ้นสุดเนื่องจากการตอบกลับแบ็กเอนด์ของฉันถูกจำกัดไว้เพียง 100 รายการเท่านั้น ดังนั้นในการพยายามหน้าแรกฉันได้รับ 100 รายการจากแบ็กเอนด์ และทุกครั้งที่เลื่อนไปจนสุดหน้า ฉันต้องการจุดสิ้นสุดการโทรสำหรับอีก 100 รายการ
ในองค์ประกอบลูกของฉัน (BpHistoryListInfiniteComponent
) ฉันตั้งค่าแอตทริบิวต์ data-load
สำหรับการติดตามเมื่อมีองค์ประกอบ 100. เข้ามาดู จากนั้นตั้งค่า IntersectionObserver
ในค่า Subject(pageByScroll$
) ของแอตทริบิวต์ data-load pageByScroll$
ของฉันต้องเริ่มต้นด้วย 0 (สำหรับความพยายามในหน้าแรก) และฉันใช้ distinct()
เพราะฉันต้องการ distinct
รายการที่โหลดแล้ว จากนั้นปล่อยค่านั้นไปยังองค์ประกอบหลักของฉัน
แต่หลังจากใช้ตัวกรองตัวใดตัวหนึ่งในองค์ประกอบหลัก ฉันต้องรีเซ็ตค่า index
เป็น 0 และส่งค่านั้นและตัวกรองไปที่แบ็กเอนด์ (และรับเพียง 100 รายการ) จากนั้นหากผู้ใช้เลื่อนไปที่ด้านล่างฉันต้องเพิ่ม index
จาก 0 อีกครั้ง แต่ distinct()
ไม่อนุญาตให้ฉันทำเช่นนั้น
ฉันต้องการรีเซ็ตค่าที่แตกต่าง
//html ส่วนหนึ่งขององค์ประกอบลูก
<div #infiniteScrollMadness class="column">
<div *ngFor="let item of history; let i = index" class="list" [attr.data-load]="(i + 1) % 100 == 0 ? (i + 1) : null">
<span>{{ item.id }}</span>
<span>{{ item.name }}</span>
</div>
</div>
.ts ส่วนหนึ่งขององค์ประกอบลูก
export class BpHistoryListInfiniteComponent implements AfterViewInit {
public pageByScroll$ = new Subject<number>();
@ViewChild("infiniteScrollMadness")
private scrollHost: ElementRef;
@Input()
history: HistoryModel;
@Input()
highlight: string;
@Output()
index = new EventEmitter<number>();
ngAfterViewInit() {
const intersectionObserver = new IntersectionObserver(
entries => {
entries
.filter(element => element.isIntersecting)
.forEach(element => {
this.pageByScroll$.next(
element.target.attributes["data-load"].value
);
});
},
{
threshold: 0.1
}
);
const mutationObserver = new MutationObserver(mutations => {
mutations.forEach(mutation => {
if (!mutation.addedNodes || mutation.type !== "childList") {
return;
}
const nodes = Array.prototype.slice.call(mutation.addedNodes, 0);
nodes.filter(node => node.nodeType === Node.ELEMENT_NODE)
.forEach((element: Element) => {
if (element.attributes["data-load"]) {
this.zone.runOutsideAngular(() => {
intersectionObserver.observe(element);
});
}
});
});
});
mutationObserver.observe(this.scrollHost.nativeElement, {
childList: true
});
this.pageByScroll$.pipe(
startWith(0),
distinct()
).subscribe(index => this.index.emit(index));
}
constructor(private zone: NgZone) {}
}
pageByScroll$
สตรีม:
- ความพยายามในหน้าแรก => ค่า: 0
- เลื่อนไปที่ด้านล่าง (+100) => ค่า: 100
- เลื่อนไปที่ด้านล่าง (+100) => ค่า: 200
- เลื่อนไปที่ด้านล่าง (+100) => ค่า: 300
- ใช้หนึ่งในตัวกรอง => ค่า: 0
- เลื่อนไปที่ด้านล่าง (+100) => ค่า: 100
- เลื่อนไปที่ด้านล่าง ( +100) => ค่า: 200