Пропустить через большой список

Итак, у меня есть список из 2000+ сотрудников, и мне нужно их отфильтровать. Как у меня сейчас, он работает очень медленно и отстает на 2 секунды. Каждый раз, когда я печатаю букву, она каждый раз проходит этот список.

Есть ли способ уменьшить отставание?

Обновить

Это пример кода:

<div style="margin-bottom:30px;" *ngIf="emulatedList">

   <input type="text" style="width:200px; background-color:#eeeeee;" name="searchText" [(ngModel)]="searchText" placeholder="Filter Dropdown List">

   <select style="background-color:#eeeeee;" [(ngModel)]="selected" placeholder="Emulate Person">
      <option *ngFor="let delegate of emulatedList | filter: searchText; trackBy: trackByName" [ngValue]="delegate.employeeid">
         {{delegate.employeename}}
      </option>
   </select>

   <span>
      <a (click)="addDelegate(selected)" style="background-color:#5B9C64; font-size:16px; color:#ffffff; padding:10px; margin-right:30px; border-radius: 10px;">Add Delegate</a>
   </span>

</div>

Файл component.ts:

ngOnInit() {   
this.personsService.getEmulateList().subscribe(data => {
  setTimeout( () => {
    //console.log(data);
    this.emulatedList = data;
  }, 300);
});

person Joel Cruz    schedule 16.05.2018    source источник
comment
Можете ли вы добавить все, что вы пробовали до сих пор?   -  person Anshuman Jaiswal    schedule 16.05.2018
comment
Это то, что я получил до сих пор. Я также обновил код тем, что было в моем файле component.ts.   -  person Joel Cruz    schedule 22.05.2018
comment
вы можете проверить мой ответ, это может помочь.   -  person Anshuman Jaiswal    schedule 22.05.2018


Ответы (4)


Вы можете использовать тайм-аут, чтобы код не запускался до тех пор, пока не будет никаких запросов в течение x секунд.

В приведенном ниже примере, несмотря на то, что doFiltering вызывается в цикле 10 раз, оператор журнала консоли печатается только один раз, ровно через 1 секунду после завершения цикла.

let handle; 

for(var i = 0; i < 10; i++) {
    doFiltering();
}

function doFiltering() {
    // Check if there is a reference to running timeout
    if (handle != null) {
        // Cancel it
        clearTimeout(handle);
    }
    // Start a timeout
    handle = setTimeout(() => {
        // Do you filtering in here
        console.log("Filtering now");
        handle = null;
    }, 1000);
}

person user184994    schedule 16.05.2018

Вместо использования канала используйте rxjs/add/operator/debounceTime как:

HTML

<input [ngModel]='filterValue' (ngModelChange)='changed($event)' />

component.ts

filterValue: string;
modelChanged: Subject<string> = new Subject<string>();

constructor() {
    this.modelChanged
        .debounceTime(500) // you can change time
        .distinctUntilChanged() // emit only when value is different from previous value
        .subscribe(value => {
            this.filterValue = value;
            // perform filter
        });
}

changed(text: string) {
    this.modelChanged.next(text);
}
person Anshuman Jaiswal    schedule 16.05.2018

Вы можете использовать debounceTime, если вы слушаете изменяющееся значение. Не уверен, что вы используете [(ngModel)] или реактивную форму. Это должно быть что-то вроде:

this.formCtrlSub = this.firstNameControl.valueChanges
  .debounceTime(1000)
  .subscribe(newValue => this.fetchNewResults());
person sabithpocker    schedule 16.05.2018

Вместо использования конвейера вы можете использовать таймер, чтобы дождаться, пока пользователь перестанет печатать, а затем отфильтровать результаты.

timer: any;

getList(searchText) {
 if (searchText.length >= 3) {
  clearTimeout(this.timer);
  this.timer = setTimeout(() => {
  // filter here
  }, 1100);
} 
else {
  this.list= [];
 }
}
person Prachi    schedule 16.05.2018