简体   繁体   English

更新pageIndex时,Angular 5 Material Paginator重置为负值

[英]Angular 5 Material Paginator resets to negative values when updating pageIndex

I'm using an Angular Material data table to display a list of objects that can be added to. 我正在使用Angular Material数据表来显示可添加到的对象列表。 When an object is added to the data source, the page index breaks and shows a negative. 将对象添加到数据源时,页面索引会中断并显示负数。 The only way I've found to fix this is to reset the page index of the material paginator to 0. However, any further changes to the paginator result in a pageIndex of -1 or a broken paginator. 我发现修复此问题的唯一方法是将材质分页器的页面索引重置为0.但是,对分页器的任何进一步更改都会导致pageIndex为-1或破坏的分页符。 Here is an example: 这是一个例子:

I first set new data in the Angular Material data source like so: 我首先在Angular Material数据源中设置新数据,如下所示:

private refreshTable() {
    // first we update the length of the paginator with the new length of the datasource data to ensure parity
    this.paginator.length = this.dataSource.data.length;


    // next we get the current page number so we can return to it later.
    let currentPage = this.paginator.pageIndex;

    this.tempSubscription2 = this.rrService.getSearchResults(this.searchEnv.outputPayload(true, true)).subscribe(
        (data: any) => {
            this.extractSBRs(data);
            this.dataSource.data = [];
            // Here is where the dataSource is reset...
            this.dataSource.data = this.sbrs;

            this.paginator.length = this.dataSource.data.length;
            this.paginator.pageIndex = 0;
            this.dataSource.paginator = this.paginator;
            console.log('made it this far');

            if (this.dataSource.paginator.pageIndex < currentPage) {
                console.log('need to return to the current page');
                this.paginator.pageIndex = currentPage;
                this.paginator._pageIndex = currentPage;
                this.dataSource.paginator.pageIndex = currentPage;
                this.dataSource.paginator._pageIndex = currentPage;

            }
        },
        (err: any) => {
        },
        () => {
        }
    );
}

When this code is run, updates from the first page are fine because the this.paginator.pageIndex is being set to 0. Once an element is added on a page greater than zero, the table shows the first page, the paginator has a pageIndex of -1 and the paginator in the UI looks like this: 当运行此代码时,第一页的更新很好,因为this.paginator.pageIndex被设置为0.一旦在大于零的页面上添加元素,表格显示第一页,该分页器有一个pageIndex为-1,UI中的paginator如下所示:

在此输入图像描述

Notice the negative index -9 - 0 . 注意负指数-9 - 0 There seem to be very few examples of updating an Angular Material Data Table and even fewer that have further notes about how updating them effects the Angular Material paginator. 似乎很少有更新Angular材料数据表的示例,甚至更少有关于如何更新它们影响Angular Material分页器的进一步说明。 How can I get the paginator to go to a pageIndex other than 0 without getting the negative index issue? 如何让paginator转到0以外的pageIndex而不会出现负面索引问题?

I've tried updating just the this.paginator which is grabbed via ViewChild() per the recommendation here . 我已经尝试更新this.paginator ,它是根据这里的建议通过ViewChild()的。 I've also tried updating the dataSource.paginator which you can see in the code above. 我也尝试更新dataSource.paginator ,你可以在上面的代码中看到。

Here are my imports: 这是我的进口:

import {
AfterContentInit, AfterViewInit, ApplicationRef, ChangeDetectorRef, 
Component, OnDestroy, OnInit,
    ViewChild
} from '@angular/core';
import { SearchEnvironment } from "../classes/search-environment";
import { SearchFilterDropdown } from "../classes/search-filter-dropdown";
import { ActivatedRoute, Router } from "@angular/router";
import {MatTableDataSource, MatPaginator, MatDialog, MatTable, MatSnackBar} from "@angular/material";
import { RemoteRetrievalService } from "../core/services/remote-retrieval.service";
import { Observable } from "rxjs/Observable";

How can I get the desired paginator behavior of returning to the currentPage index without causing a negative index in the paginator.pageIndex value or the bad user experience of the negative values in the item(s) range? 如何在不导致paginator.pageIndex值中的负索引或项目范围中负值的错误用户体验的情况下获得返回到currentPage索引的所需分页符行为?

It is strange how they build some of these components. 他们如何构建这些组件是很奇怪的。 I am not sure my solution will work, but based upon what I've read in the issue it seems that they can not handle both a length change and pageIndex change in the same digest cycle. 我不确定我的解决方案是否有效,但根据我在该问题中所阅读的内容,它们似乎无法在同一摘要周期中处理length更改和pageIndex更改。

So I would recommend changing the length first, and then later changing the pageIndex . 所以我建议先改变length ,然后再改变pageIndex

 this.paginator.length = this.dataSource.data.length;
 this.paginator.pageIndex = 0;
 this.dataSource.paginator = this.paginator;
 console.log('made it this far');

The above sets the values we know will work on the component, and the next part uses window.setTimeout to run the next set of changes after the component has had a chance to update itself. 上面设置了我们知道将在组件上工作的值,下一部分使用window.setTimeout在组件有机会更新自身后运行下一组更改。

 if (this.dataSource.paginator.pageIndex < currentPage) {
     window.setTimeout(()=>{
         this.zone.run(()=>{
            console.log('need to return to the current page');
            this.paginator.pageIndex = currentPage;
            this.paginator._pageIndex = currentPage;
            this.dataSource.paginator.pageIndex = currentPage;
            this.dataSource.paginator._pageIndex = currentPage;
            // EDIT: You must then set the datasource paginator back to the newly edited paginator. 
            this.dataSource.paginator = this.paginator;
         });
     });
 }

You will need to inject NgZone to run the code inside Angular's zones (which is for error handling). 您需要注入NgZone来运行Angular区域内的代码(用于错误处理)。 It's just a good practice when using window.setTimeout . 使用window.setTimeout时这是一个很好的做法。

Keep in mind that window doesn't exist in Angular Universal incase you want to later to do server side rendering, but that's a different issue. 请记住,Angular Universal中不存在window ,您希望稍后进行服务器端渲染,但这是一个不同的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM