ng-select
已经支持虚拟滚动。请利用此功能来适合您的代码!请在下面找到一个工作示例!
import { Component, ElementRef, ViewChild } from '@angular/core';
import { FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { of } from 'rxjs';
import { delay } from 'rxjs/operators';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';
import { NgSelectModule } from '@ng-select/ng-select';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-root',
standalone: true,
imports: [
FormsModule,
NgSelectModule,
CommonModule,
ReactiveFormsModule,
RouterModule,
],
template: `
<div class="col-6">
<label>device</label>
<div class="input-group" style="height:100vh;">
<ng-select
[virtualScroll]="true"
[items]="extractedOptions"
bindLabel="label"
bindValue="id"
placeholder="Select device"
(scroll)="onScroll($event)"
(scrollToEnd)="onScrollToEnd()"
[multiple]="true"
>
<ng-template ng-label-tmp let-item="item">
{{ item.label }}
</ng-template>
<ng-template ng-option-tmp let-item="item" let-search="searchTerm" let-index="index">
{{ item.label }}
</ng-template>
</ng-select>
</div>
</div>
`,
})
export class App {
@ViewChild('deviceSelect') deviceSelect!: ElementRef;
deviceform!: FormGroup;
loading: any;
options: any = [];
totalCount: any;
extractedOptions: any = [];
numberOfItemsFromEndBeforeFetchingMore = 10;
constructor() {}
title: string = 'New Device';
page: number = 1;
IsEdit: boolean = false;
items_per_page: number = 10;
ngOnInit() {
this.loadOptions();
}
loadOptions() {
console.log('asdf')
this.loading = true;
const start = this.page;
const data = new Array(50).fill(null).map((item, i) => ({
name: start + i,
id: start + i,
}));
of({
data: {
records: data,
count: {
total: 100,
},
},
})
// .pipe(delay(1000))
.subscribe((response: any) => {
const records = response.data.records;
const extractedOptions = records.map((record: any) => ({
label: record.name,
value: record.id,
}));
this.totalCount = response.data.count.total;
this.extractedOptions.push(...extractedOptions);
this.extractedOptions = [...this.extractedOptions]
this.page++;
this.loading = false;
});
}
onScrollToEnd() {
this.loadOptions();
}
onScroll(event: any) {
console.log(event, this.extractedOptions.length);
if (this.loading || this.extractedOptions.length > this.totalCount) {
return;
}
if (event.end >= this.extractedOptions.length) {
this.loadOptions();
}
}
shouldDisplayError(controlName: string): boolean {
const control = this.deviceform.get(controlName);
return control ? control.touched : false;
}
// @HostListener('scroll', ['$event'])
// onScroll(event: any) {
// console.log('testing');
// const target = event.target || event.srcElement;
// if (target.offsetHeight + target.scrollTop >= target.scrollHeight) {
// // Fetch more options when scrolled to the bottom
// this.loadOptions();
// }
// }
}
bootstrapApplication(App);
堆栈闪电战