【问题标题】:How to reset RxJS distinct in angular2如何在angular2中重置RxJS不同
【发布时间】:2019-03-24 03:04:58
【问题描述】:

我需要实现无限滚动,因为我的后端响应仅限于 100 个项目。所以在第一页尝试我从后端收到 100 个项目。在每次滚动到页面末尾时,我都需要为另外 100 个项目调用端点。

在我的子组件 (BpHistoryListInfiniteComponent) 中,我设置了 data-load 属性以跟踪 100. 元素何时出现。然后在数据加载属性的 Subject(pageByScroll$) 值中设置IntersectionObserver。我的 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

【问题讨论】:

    标签: javascript angular rxjs ngrx


    【解决方案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) 手动重置它

    【讨论】:

    • 非常感谢,这正是我需要的
    猜你喜欢
    • 1970-01-01
    • 2017-03-03
    • 1970-01-01
    • 2016-05-14
    • 1970-01-01
    • 2017-05-04
    • 2016-11-17
    • 2017-10-16
    • 1970-01-01
    相关资源
    最近更新 更多