วิธีรีเซ็ต RxJS แตกต่างใน Angular2

ฉันจำเป็นต้องใช้การเลื่อนแบบไม่สิ้นสุดเนื่องจากการตอบกลับแบ็กเอนด์ของฉันถูกจำกัดไว้เพียง 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


person mario89    schedule 23.03.2019    source แหล่งที่มา


คำตอบ (1)


คุณสามารถจัดการมันได้เช่นนี้

this.resets$ = new Subject();
this.resets$.pipe(
  startWith(null),
  switchMap(() => this.pageByScroll$.pipe(
    startWith(0),
    distinct()
  ))
).subscribe(this.index);

นี่จะเป็น "ขอบเขต" distinct โอเปอเรเตอร์เป็น switchMap และคุณสามารถรีเซ็ตได้ด้วยตนเองโดย this.resets$.next(null)

person Andrei    schedule 23.03.2019
comment
ขอบคุณมาก นี่คือสิ่งที่ฉันต้องการ - person mario89; 25.03.2019