Ok узнал больше о внутреннем устройстве ng-select и решении для правильной выпадающей фильтрации как одного типа.
Ключом к пониманию этого является этот оператор в собственной функции фильтрации компонента, показанной здесь.
const match = this._ngSelect.searchFn || this._defaultSearchFn;
Этот оператор позволяет пользователю внедрить функцию, если ее нет; тогда используется searchFn по умолчанию.
Чтобы ввести свой собственный SearchFn, поместите его в ng-select html. Вам понадобится это для определенного c сложного поиска.
<ng-select
[searchFn]="searchFunction" //inject your own function here.
[items]="filtered"
type="text">
// the itemsList is iterated and this is called for each item
// just like an array map function
searchFunction(term, item) {
// anything returning true makes it into the filtered list
return item.firstName.includes(term);
}
//any matches are pushed into the itemsList.filteredItems list which is read-only to the outside world.
//see this line up above in the filter method of the ng-select?
this._filteredItems.push(...matchedItems);
Если у вас нет зарегистрированного метода SearchFn, вызывается defaultSearchFn. Эта функция выглядит так:
_defaultSearchFn(search, opt) {
/** @type {?} */
const label = stripSpecialChars(opt.label).toLocaleLowerCase();
return label.indexOf(search) > -1;
}
Эта функция не смогла ничего найти в моей ситуации, потому что не было opt.label. Я считаю, что это ошибка, потому что я использовал шаблон tmp-lbl. В режиме отладки все элементы при входе были правильными, но индекс так и не был найден.
Здесь был шаблон ng-label-tmp, который должен был установить значение opt.label.
<ng-template ng-label-tmp let-item="item">
<span>{{ item.firstName + " " + item.lastName }}</span>
</ng-template>
[bindLabel] не работал, потому что он привязывается только к отдельным полям.
Если у вас нет зарегистрированного Searchfn и ничего не найдено через _defaultSearchFn, тогда последний шанс упущен для пользователя, если вы зарегистрировали обработчик onSearch, подобный этому.
(search)="onSearchFunction($event, select)"
Но вы не можете получить доступ к itemsList.FilteredItems отсюда, поскольку он доступен только для чтения. Событие отправляет термин и элементы, над которыми нужно работать.
Доступ к нему также осуществляется из следующего кода:
@ViewChild(NgSelectComponent, { static: false }) select: NgSelectComponent;
this.select.searchEvent.subscribe((result) => {
let term = result.term;
result.items = this.filtered.find((item) =>
item.firstName.includes(term)
);
});
Обратите внимание, что этот метод требует, чтобы вы поддерживали и связывали собственный фильтр список. Фу ...
Лучшее решение - использовать вашу собственную функцию встроенного поиска.