Вход - список рекомендуемых значений, выход - результат ввода. Значения предлагаются по вхождению подстроки.
Компонент будет состоять из двух составляющих: input и dropdown.
Описание компонента:
Поле | Значение |
---|---|
@Input items: Array<string> |
Входной список строк. |
@Output onChange: EventEmitter<string> |
Аутпут результата. |
filteredItems: Array<string> |
Массив строк, фильтрующийся при изменении инпута в шаблоне, отображается в дропдауне. |
constructor(private elementRef: ElementRef) |
Конструктор с инжектом elementRef для обработки «внешнего» клика. |
@HostListener(document:click) onBlur |
Обработчик внешнего клика, если таргет не из datalist-компонента — вызываем closeDropdown . |
ngOnChanges({items}: {items: SimpleChange}) |
Ресетит filteredItems = items , сбрасывает displayedValue . |
displayedValue: string |
Значение отображаемое в инпуте. |
isOpen: boolean |
Состояние дропдауна |
onInput(event: Event): void |
Обработчик изменений инпута, достает из ивента значение инпута и вызывает setValue . |
onSelect(value: string): void |
Обработчик выбора элемента в дропдауне, вызывает setValue(value) и closeDropdown() . |
setValue(value: string): void |
Метод установки значения. Сеттит displayValue , фильтрует items по value и сеттит filteredItems , эмиттит значение. |
openDropdown(): void |
Открывает дропдаун, т.е сеттит isOpen = true . |
closeDropdown(): void |
Закрывает дропдаун, т.е сеттит isOpen = false . |
Эту итерацию считаю опциональной, вместо этого в компонент можно передавать уже преобразованные данные.
Поле | Значение |
---|---|
@Input() valueAccessor: { getValue(item):string } |
Объект с методом, позволяющим достать значение для отображение в инпуте и дропдауне. Дефолтным значением можно задать объект с методом, который просто возвращает item, так мы сделаем этот инпут опциональным. |
-
Обработчик «внешнего» клика можно вынести в директиву.
-
Можно сделать datalist компонентом-агностиком, передав в него компонент выступающий в качестве элемента списка. (ngComponentOutlet и тд)