Ускорение автозаполнения материалов Angular или альтернативы

Я использую автозаполнение Angular Materials, чтобы позволить пользователю искать строку формата: «[ID #] - [Текстовое описание]». Данные предварительно извлекаются в самом начале загрузки страницы и содержат около 39 000 строк.

Мой HTML-код:

<md-input-container>
    <input mdInput placeholder="TSN Search" [mdAutocomplete]="auto" [formControl]="TSN_Ctrl">
</md-input-container>

<md-autocomplete #auto="mdAutocomplete">
    <md-option *ngFor="let tsn of filtered_TSNs | async" [value]="tsn">
        {{ tsn }}
    </md-option>
</md-autocomplete>

И мой машинописный код:

TSN_Ctrl: FormControl = new FormControl();
filtered_TSNs: any;

constructor(){
    this.filtered_TSNs = this.TSN_Ctrl.valueChanges
        .startWith(null)
        .map(val => val ? this.filter_TSNs(val) : this.dataService.tsnTitles.slice());
}

private filter_TSNs(val: string) {
    return this.dataService.tsnTitles.filter(option => new RegExp(`^${val}`, 'gi').test(option));
}

По сути, я использую стандартный код из примера Angular Materials с небольшой адаптацией.

Функция автозаполнения невероятно медленная и практически не отвечает. Я понимаю, что есть много вариантов (строк 39k), но они предварительно извлекаются и хранятся локально.

Могу ли я что-то сделать, чтобы ускорить это, или в списке слишком много строк? Если я изменю метод фильтрации и строки так, чтобы они содержали только поле идентификатора, может ли это ускорить процесс? Нужно ли мне использовать совершенно другую библиотеку (например, если известно, что автозаполнение Angular Materials работает медленно)?


person dandev91    schedule 21.07.2017    source источник
comment
Попробуйте добавить console.time к вашему методу filter_TSNs, чтобы увидеть, сколько времени занимает каждый фильтр, хотя я ожидаю, что это будет довольно быстро. Настоящим виновником, вероятно, является автозаполнение/угловая попытка отобразить компоненты опций 39k (!) Возможно, вы захотите вернуть подмножество в filter_TSNs (например, первые 50 опций)   -  person Will Howell    schedule 21.07.2017
comment
Уилл, ты гений. В итоге я запустил функцию filter_TSNs только после того, как пользователь ввел не менее 5 символов. Подмножества, возвращаемые после того, как первые 5 символов резко сокращаются (50 или около того), и проблема была связана с автозаполнением/угловым, а не с самой функцией фильтра.   -  person dandev91    schedule 24.07.2017


Ответы (3)


Совет Уилла Хауэлла: «Настоящим виновником, вероятно, является автозаполнение / угловая попытка отобразить компоненты параметров 39k (!) Вы можете захотеть вернуть подмножество в filter_TSN (например, первые 50 параметров)» был проблемой и должен быть принятым ответом. Ограничив функцию поиска отображением результатов автозаполнения только до 4-го символа, автозаполнение стало мгновенным.

person dandev91    schedule 18.09.2017
comment
Для тех, кто может спросить, вы можете добиться этого, выполнив: .map(val => val.length >= 4 ? this.filter_TSNs(val) : []); - person Peekyou; 08.11.2018

Другим решением может быть использование Virtual Scroll из Angular CDK.

<mat-autocomplete #auto="matAutocomplete">
    <cdk-virtual-scroll-viewport itemSize="48" style="height: 256px">
        <mat-option *cdkVirtualFor="let tsn of filtered_TSNs | async" [value]="tsn">
          {{ tsn }}
        </mat-option>
    </cdk-virtual-scroll-viewport>
</mat-autocomplete>

height: 256px важен, иначе вы его не увидите.

person Robouste    schedule 25.07.2019
comment
Спасибо, я думаю, что это решение более элегантно) - person Azamat; 11.09.2019
comment
ОБНОВЛЕНИЕ: в настоящее время существуют некоторые проблемы с использованием виртуальной прокрутки внутри MatAutocomplete, здесь описание - person Azamat; 11.09.2019

Фильтрация после проверки длины значения сделала эту работу, как упоминалось PeekYou

person MadhuB    schedule 04.12.2018
comment
Хотя эта ссылка может ответить на вопрос, лучше включить сюда основные части ответа и предоставить ссылку для справки. Ответы, содержащие только ссылки, могут стать недействительными, если связанная страница изменится. как ответить - person Agilanbu; 04.12.2018