Рассмотрим сценарий, в котором у нас есть длинный список данных, отображаемых пользователю на пользовательском интерфейсе. Для пользователя было бы громоздко искать какое -либо конкретное ключевое слово в этом длинном списке без каких -либо функций поиска. Следовательно, чтобы упростить жизнь наших пользователей, мы обычно внедряли поисковые фильтры в нашем пользовательском интерфейсе.
Итак, теперь вопрос в том, как его реализовать? Это довольно просто, хотя 😉 Все, что мы хотим, – это фильтр, который принимает массив в качестве ввода и возвращает подмножество этого массива на основе термина, который мы поставляем. В угловании этот способ преобразования данных в какую -то другую форму реализован с Трубы Анкет Давайте сначала поймем немного больше о трубы Прежде чем мы начнем реализацию.
Трубы в угловых
Труба принимает данные в качестве входных данных и преобразует их в желаемый выход. Труба может использоваться как в выражении шаблона HTML, так и в компоненте. Angular действительно предоставляет нам некоторые встроенные трубы, такие как CurrencyPipe, DatePipe, Decimalpipe и т. Д. Проверьте этот фрагмент кода ниже, чтобы увидеть его в действии.
dateObj = Date.now();
// HTML template expression syntax using pipe operator (|)
{{ dateObj | date }} // output is 'Jun 15, 2015'
{{ dateObj | date:'medium' }} // output is 'Jun 15, 2015, 9:43:11 PM'
{{ dateObj | date:'shortTime' }} // output is '9:43 PM'
{{ dateObj | date:'mm:ss' }} // output is '43:11'
// Using in component
constructor(private datePipe: DatePipe) {
console.log(datePipe.transform(Date.now(),'yyyy-MM-dd'));
//2019-07-22
}
Трубы из 2 типов – чистые и нечистые. Для получения дополнительной информации об угловых трубах, Посетите эту ссылку Анкет
Реализация поискового фильтра
1. Создать фильтрующую трубу
Давайте заполним трубу кодом для фильтра. Скопируйте и вставьте этот код в Filter.pipe.ts :
// filter.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({ name: 'appFilter' })
export class FilterPipe implements PipeTransform {
/**
* Pipe filters the list of elements based on the search text provided
*
* @param items list of elements to search in
* @param searchText search string
* @returns list of elements filtered by search text or []
*/
transform(items: any[], searchText: string): any[] {
if (!items) {
return [];
}
if (!searchText) {
return items;
}
searchText = searchText.toLocaleLowerCase();
return items.filter(it => {
return it.toLocaleLowerCase().includes(searchText);
});
}
}
Это определение трубы раскрывает следующие ключевые моменты:
- Труба – это класс, украшенный метаданными трубками.
- Класс трубы реализует метод преобразования интерфейса Pipetransform, который принимает входное значение, за которым следует дополнительные параметры и возвращает -трансформированное значение. В нашей трубе фильтров требуется 2 входа –
массивиПоиск текстЧтобы фильтровать массив. - Чтобы сказать, что это труба, мы применяем
@Pipe Decorator, который мы импортируем из основной угловой библиотеки. - Декоратор @pipe позволяет нам определить имя трубы, которое мы будем использовать в выражениях шаблона. Это должен быть действительный идентификатор JavaScript. Имя нашей трубы
AppfilterАнкет
2. Использование трубы
Во -первых, чтобы использовать трубу, нам нужно импортировать ее в модуль приложения. Наш app.module.ts Файл теперь будет выглядеть так:
// app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { FilterPipe } from './pipes/filter.pipe'; // -> imported filter pipe
@NgModule({
declarations: [
AppComponent,
FilterPipe // -> added filter pipe to use it inside the component
],
imports: [
BrowserModule,
FormsModule
],
bootstrap: [AppComponent]
})
export class AppModule { }
Теперь мы можем использовать фильтрующую трубу в нашем Компонент приложения Анкет Давайте предположим, что в нашем app.component.html У нас есть окно ввода, в которое мы можем ввести наш SearchText и список, который использует это труба Чтобы фильтровать результаты.
- {{c}}
// app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'angular-text-search-highlight';
searchText = '';
characters = [
'Ant-Man',
'Aquaman',
'Asterix',
'The Atom',
'The Avengers',
'Batgirl',
'Batman',
'Batwoman',
...
]
}
Вот и все! Теперь, когда мы запустим наше приложение, мы увидим следующий вывод:
Но эй! Наши результаты поиска не выделяются, как это было показано в начале 😟
Причина в том, что Трубы В угловании только преобразует данные, передаваемые им в желаемый выход. Он не манипулирует HTML, связанным с ним. Чтобы выделить результаты поиска, нам потребуется манипулировать HTML, чтобы выделить SearchText Часть этого. Это может быть достигнуто с помощью Директивы Анкет
Директивы в угловых
Угловые директивы используются для расширения мощности HTML, давая ему новый синтаксис. Есть 3 типа директив:
- Компоненты – Директивы с шаблоном.
- Структурные директивы – Измените макет DOM, добавив и удаляя элементы DOM.
- Директивы атрибутов – измените внешний вид или поведение элемента, компонента или другой директивы.
Покрытие директив выходит за рамки этого поста. Если вы хотите узнать больше об угловых директивах, Посетите эту ссылку Анкет
Реализация директивы в нашем приложении
В нашем случае мы будем использовать Директива атрибутов Чтобы выделить SearchText В списке результатов.
1. Создание директивы выделения
Директива атрибута, минимально требует создания класса контроллера, аннотированного с @Directive, которая указывает селектор, который идентифицирует атрибут. Класс контроллера реализует желаемое директивное поведение.
Давайте заполним директиву кодом для выделения. Скопируйте и вставьте этот код в hight.pipe.ts :
// highlight.directive.ts
import { Directive, Input, SimpleChanges, Renderer2, ElementRef, OnChanges } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective implements OnChanges {
@Input() searchedWord: string; // searchText
@Input() content: string; // HTML content
@Input() classToApply: string; //class to apply for highlighting
@Input() setTitle = false; //sets title attribute of HTML
constructor(private el: ElementRef, private renderer: Renderer2) { }
ngOnChanges(changes: SimpleChanges): void {
if (!this.content) {
return;
}
if (this.setTitle) {
this.renderer.setProperty(
this.el.nativeElement,
'title',
this.content
);
}
if (!this.searchedWord || !this.searchedWord.length || !this.classToApply) {
this.renderer.setProperty(this.el.nativeElement, 'innerHTML', this.content);
return;
}
this.renderer.setProperty(
this.el.nativeElement,
'innerHTML',
this.getFormattedText()
);
}
getFormattedText() {
const re = new RegExp(`(${this.searchedWord})`, 'gi');
return this.content.replace(re, `${this.classToApply}">$1`);
}
}
Логика состоит в том, чтобы манипулировать текущим элементом HTML, добавив метки между SearchText и применять класс выделения к нему.
2. Использование директивы
Во -первых, чтобы использовать трубу, нам нужно импортировать ее в модуль приложения. Наш app.module.ts Файл теперь будет выглядеть так:
// app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { HighlightDirective } from './directives/highlight.directive'; // -> imported directive
import { FilterPipe } from './pipes/filter.pipe';
@NgModule({
declarations: [
AppComponent,
HighlightDirective, // -> added directive
FilterPipe
],
imports: [
BrowserModule,
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Чтобы использовать эту директиву в нашем HTML -файле, мы добавим ее в качестве обычного атрибута HTML со всеми его параметрами. Это было бы похоже на это:
- {{c}}
Теперь мы сможем увидеть желаемый результат! 😌
Вы проверяете мой GitHub Repo Для полной реализации этого поста.
До встречи! до моего следующего поста 😋
Оригинал: “https://dev.to/idrisrampurawala/creating-a-search-filter-in-angular-562d”