【问题标题】:Angular Material VirtualScrollViewPort - load data asyncAngular Material VirtualScrollViewPort - 异步加载数据
【发布时间】:2019-01-02 16:28:07
【问题描述】:

我为VirtualScrollViewPort 找到了不同的示例,但我仍然有如何在现实生活中使用它们的问题。样本一次从服务器加载整个数据 - 但由于它们太大,我想单独加载它们。我的主要要求是:

  1. 搜索掩码 - 用户输入一些数据
  2. 显示进度条...
  3. 在服务器上查询搜索
  4. 如果没有找到结果 ==> 显示一条消息
  5. 如果找到某些东西 ==> 显示前 n (=10) 项
  6. 在用户向下滚动并且仅例如剩下 5 个项目 ==> 额外加载 10 个项目
    • 继续 5。
    • 如果只是例如剩下 3 个 ==> 结束滚动

我已经尝试了 Specifying data 部分的方法 - 但是我无法识别没有加载任何数据并且我无法启动视图 - 特别是当用户重置内容时。

我也试过了

<cdk-virtual-scroll-viewport itemSize="itemHeight" (scrolledIndexChange)="nextBatch($event,(resultList[resultList.length-1].total) )"
class="scroll-container">
  <div *cdkVirtualFor="let search of resultList"  class="card-item" >

这适用于第一个要求,但最后我失败了 scrolledIndexChange 仅在列表中的第一个项目上被触发。我不知道如何跟踪用户是否已经在显示第 6 项(这将加载其他数据)。在API page 上,我在scrolledIndexChange 旁边看不到任何@Output()

任何提示如何正确跟踪事件?

更新 我发现的第一个问题是设置高度的语法不正确,即[itemSize]="itemHeight" 是适当的语法,否则它始终为零 ==> 所有元素都被渲染!

【问题讨论】:

    标签: angular angular-material angular7


    【解决方案1】:

    经过一些工作,我的最终解决方案如下所示:

    <ng-container *ngIf="lstSearchResults|async as resultList; else searching">
        <cdk-virtual-scroll-viewport [itemSize]="itemHeight" (scrolledIndexChange)="nextBatch()"
             class="scroll-container">
           <div *cdkVirtualFor="let search of resultList"  class="card-item">
    

    值得注意的是,我的列表是一个异步列表,名为 lstSearchResults,在我拥有的 ts 代码中:

    // for proper height and caching... (in pixels)
    itemHeight = 174;
    
    search(searchConfig: SearchOptions): void {
        //    ....
        this.lstSearchResults = new BehaviorSubject<SearchResult[]>(null);
        // call the REST service
        this.searchService.doSearch(searchConfig).subscribe((foundEntry) => {
            if (!this.resultList) {
                // first list - nothing found up till now
                this.resultList = foundEntry;
            } else {
                if (!this.resultList[this.resultList.length - 1]) {
                    //remove the marker (which was added below/previously)
                    this.resultList.pop();
                }
                foundEntry.map((item) => this.resultList.push(item));
            }
            if (this.resultList[0] && this.resultList[0].total > this.resultList.length + 1) {
                //some more elements could be fetched from the server ==> add a dummy entry for rendering
                this.resultList.push(undefined);
            }
            // notify the search list to be updated
            this.lstSearchResults.next(this.resultList);
        });
    }
    

    对于滚动,我有以下代码:

    nextBatch(): void {
        if (this.theEnd) {
            return;
        }
    
        if (this.resultList[0]) {
            // something was found
            if (
                this.viewport.getRenderedRange().end ===
                this.viewport.getDataLength()
            ) {
                // since we scrolled to the very end of the rendered display
                // ==> check if further search is required (and do so...)
                const searchTotal = this.resultList[0].total;
                this.mySearchConfig.posOffset += this.mySearchConfig.noOfElements;
                // some basic check if the total counter exceeds the current offset
                // i.e. no further search required
                if (this.mySearchConfig.posOffset <= searchTotal) {
                    this.search(this.mySearchConfig, true);
                } else {
                    this.theEnd = true;
                }
            }
        } else {
            // nothing found ==> mark the end
            this.theEnd = true;
        }
    }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-04-11
      • 2019-10-05
      • 1970-01-01
      • 1970-01-01
      • 2018-01-10
      • 2019-09-28
      • 1970-01-01
      相关资源
      最近更新 更多