jqxGrid 虚拟滚动为空 space 或插入空行

jqxGrid Virtual scrolling empty space OR Empty rows inserted

我正在使用 ASP.NET 零项目在 Angular 5 中实现虚拟滚动。 滚动后我看到了一些空白区域(比如说 startIndex=6 和 endIndex=25)。即使网格有数据要显示,有些行也不会显示。 这个问题一直发生到 startIndex=19 和 endIndex=38(缺失行数增加),但是一旦滚动到 startIndex=20 和 endIndex=398,它又开始正常工作。

最初的网格视图是这样的 -

滚动到 20 条记录后 -

当我们滚动到 36 条记录时,它会加载所有以前的页面数据,如下所示 -

我的代码如下 –

<jqxGrid #customersGrid [width]="'100%'" [height]="450" [source]="dataAdapter" [columns]="columns" [virtualmode]="true" [rendergridrows]="rendergridrows" (onRowselect)="rowSelect($event)" [filterable]="true" (onFilter)="filterCustomers()" [autoshowfiltericon]="true" [updatefilterconditions]="updatefilterconditions" [sortable]="true" (onSort)="sortCustomers($event)" [altrows]="true" [selectionmode]="'singlerow'"></jqxGrid>

component.ts代码-

import { jqxGridComponent } from 'jqwidgets-framework/jqwidgets-ts/angular_jqxgrid';
import {
  CustomerServiceProxy,
  CustomerListDto,
  EntityDtoOfInt64,
  FilterRule
} from 'shared/service-proxies/service-proxies';
@Component({
  templateUrl: './customers.component.html',
  styleUrls: ['./customers.component.less'],
  animations: [appModuleAnimation()]
})
export class CustomersComponent extends AppComponentBase implements OnInit {
 @ViewChild('customersGrid') customersGrid: jqxGridComponent;

 customers: Array<CustomerListDto> = [];
  isGridDataPrepared = false;
  rendergridrows: any;
  source: any;
  dataAdapter: any;

  columns: any[] = [
    {
      pinned: true,
      exportable: false,
      sortable: false,
      menu: false,
      text: '',
      columntype: 'number',
      cellclassname: 'jqx-widget-header',
      cellsrenderer: this.numberRenderer,
      width: '4%'
    },
    {
      text: this.l('CustomerNumber'),
      datafield: 'customerNumber',
      cellsalign: 'center',
      width: '10%'
    },
    {
      text: this.l('CustomerName'),
      datafield: 'lastNameFirstCo'
    },
    {
      text: this.l('CustomerAddress'),
      datafield: 'address'
    },
    {
      text: this.l('CustomerAddress2'),
      datafield: 'address2'
    },
    {
      text: this.l('CustomerCity'),
      datafield: 'city'
    },
    {
      text: this.l('CustomerState'),
      datafield: 'state',
      cellsalign: 'center',
      width: '8%'
    },
    {
      text: this.l('CustomerZip'),
      datafield: 'zip',
      cellsalign: 'center',
      width: '10%'
    },
    {
      text: this.l('Active'),
      datafield: 'isActive',
      cellsalign: 'center',
      filtertype: 'checkedlist',
      filteritems: [{ value: true, label: 'YES' }, { value: false, label: 'NO' }],
      cellsrenderer: this.boolRenderer,
      width: '8%'
    }
  ];

  filters: {
    sorting: string;
    params: { startindex: number; endindex: number };
  } = {
      sorting: 'lastNameFirstCo asc',
      params: { startindex: 0, endindex: this.pageSize }
    };

    constructor(
    injector: Injector,
    private customerService: CustomerServiceProxy
  ) {
    super(injector);
  }


  ngOnInit(): void {
    this.obj = new FilterRule();
    this.initGrid();
    this.getCustomers();
  }

  initGrid() {
    this.customers = [];
    this.source = {
      datatype: 'json',
      datafields: [
        { name: '', type: 'number' },
        { name: 'customerNumber', type: 'string' },
        { name: 'lastNameFirstCo', type: 'string' },
        { name: 'address', type: 'string' },
        { name: 'address2', type: 'string' },
        { name: 'city', type: 'string' },
        { name: 'state', type: 'string' },
        { name: 'zip', type: 'number' },
        { name: 'isActive', type: 'boolean' }
      ],
      localdata: {},
      sortcolumn: 'lastNameFirstCo',
      sortdirection: 'asc',
      totalrecords: 10000000
    };
    this.dataAdapter = new jqx.dataAdapter(this.source);
  }


  getCustomers(from, isFromInit: boolean = false) {
    this.customerService
      .getCustomers(
        '',
        this.obj.condition,
        this.obj.field,
        this.obj.id,
        this.obj.input,
        this.obj.operator,
        this.obj.rules,
        this.obj.type,
        this.obj.value,
        this.filters.sorting,
        this.pageSize,
        this.filters.params.startindex
      )
      .debounceTime(500)
      .subscribe(result => {
        if (result.totalCount >= 0) {
          this.customers = result.items;
          // this.customers.slice(0, this.filters.params.startindex);
          // this.customers = this.customers.concat(result.items);
          this.source.totalrecords = result.totalCount;
          // this.customersGrid.updatebounddata('sort');
        } else {
          this.customers = [];
          this.source.totalrecords = 0;
        }


        if (isFromInit) {
          let lastIndex = this.pageSize;
           // load virtual data.
          this.rendergridrows = (params: any): any[] => {
           this.filters.params = params;

            this.customers = _.takeWhile(
              this.customers,
              customer => customer.id
            );

            return this.customers;
           };


          this.isGridDataPrepared = true;
          }
      });
  }

 }

注意—— 1.我用了PageSize = 20

  1. 在网格中显示 15 条记录

  2. 问题是从行号 21 滚动到 35 时添加了空行,之后它工作正常。

请朋友帮忙...

为了解决上述问题,我们必须在本地维护一个 Array 对象,并将新接收到的数据插入到我们的本地数组中。

例如-

@Component({
  templateUrl: "./employee.component.html",
  styleUrls: ["./employee.component.less"],
  animations: [appModuleAnimation()]
})

export class EmployeesComponent extends AppComponentBase implements OnInit {
 @ViewChild("employeesGrid") employeesGrid: jqxGridComponent;
employees: Array<EmployeeListDto> = [];

rendergridrows = (params: any): any[] => {
//get data from server then append in employees array
return this.employees;
}

}