Выделите текст поиска - angular 2
Посланник отображает результаты поиска на основе ввода, заданного пользователем. Необходимо выделить искомое слово, показывая результат.
Это html и компонент, который был использован.
Component.html
<div *ngFor = "let result of resultArray">
<div>Id : result.id </div>
<div>Summary : result.summary </div>
<div> Link : result.link </div>
</div>
Component.ts
resultArray : any = [{"id":"1","summary":"These are the results for the searched text","link":"http://www.example.com"}]
Этот результатArray извлекается из бэкэнда-сервиса, отправив текст поиска в качестве входного. На основе текста поиска результат будет получен. Необходимо выделить искомый текст, аналогичный поиску google. Пожалуйста, найдите скриншот,
![введите описание изображения здесь]()
Если я ищу слово "член", то появляется слово "член". Как достичь того же, используя angular 2. Пожалуйста, предложите идею об этом.
Ответы
Ответ 1
Вы можете сделать это, создав канал и применив этот канал к итоговой части массива внутри ngfor
. Вот код для Pipe
:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'highlight'
})
export class HighlightSearch implements PipeTransform {
transform(value: any, args: any): any {
if (!args) {return value;}
var re = new RegExp(args, 'gi'); //'gi' for case insensitive and can use 'g' if you want the search to be case sensitive.
return value.replace(re, "<mark>" + args + "</mark>");
}
}
и затем в разметке примените это к строке как это:
<div innerHTML="{{ str | highlight : 'search'}}"></div>
Замените "поиск" словом, которое вы хотите выделить.
Надеюсь, это поможет.
Ответ 2
Выбранный ответ имеет следующие проблемы:
- Он вернет undefined, если в строке поиска ничего не указано
- Поиск должен быть нечувствительным к регистру, но не должен заменять исходный случай строки.
я бы предложил вместо этого следующий код
transform(value: string, args: string): any {
if (args && value) {
let startIndex = value.toLowerCase().indexOf(args.toLowerCase());
if (startIndex != -1) {
let endLength = args.length;
let matchingString = value.substr(startIndex, endLength);
return value.replace(matchingString, "<mark>" + matchingString + "</mark>");
}
}
return value;
}
Ответ 3
Одна из трудностей, с которой сталкивается метод innerHTML, - это стиль тега <mark>
. Другой способ - разместить это в компоненте, позволяя гораздо больше вариантов стилизации.
выделены-text.component.html
<mark *ngIf="matched">{{matched}}</mark>{{unmatched}}
<сильные > Выделенные-text.component.ts
import { Component, Input, OnChanges, OnInit } from "@angular/core";
@Component({
selector: "highlighted-text",
templateUrl: "./highlighted-text.component.html",
styleUrls: ["./highlighted-text.component.css"]
})
export class HighlightedTextComponent implements OnChanges {
@Input() needle: String;
@Input() haystack: String;
public matched;
public unmatched;
ngOnChanges(changes) {
this.match();
}
match() {
this.matched = undefined;
this.unmatched = this.haystack;
if (this.needle && this.haystack) {
const needle = String(this.needle);
const haystack = String(this.haystack);
const startIndex = haystack.toLowerCase().indexOf(needle.toLowerCase());
if (startIndex !== -1) {
const endLength = needle.length;
this.matched = haystack.substr(startIndex, endLength);
this.unmatched = haystack.substr(needle.length);
}
}
}
}
выделены-text.component.css
mark {
display: inline;
margin: 0;
padding: 0;
font-weight: 600;
}
Использование
<highlighted-text [needle]=searchInput [haystack]=value></highlighted-text>
Ответ 4
Чтобы расширить ответ Камаля,
Значение, входящее в метод преобразования, может быть числом, возможно, приведение в строку String(value)
было бы безопасным.
transform(value: string, args: string): any {
if (args && value) {
value = String(value); // make sure its a string
let startIndex = value.toLowerCase().indexOf(args.toLowerCase());
if (startIndex != -1) {
let endLength = args.length;
let matchingString = value.substr(startIndex, endLength);
return value.replace(matchingString, "<mark>" + matchingString + "</mark>");
}
}
return value;
}
Ответ 5
Если в вашей строке несколько слов, используйте конвейер, который принимает массив и выделяет каждое слово в результате.
Вы можете использовать следующую трубу для нескольких поисковых слов: -
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'highlight'
})
export class HighlightText implements PipeTransform {
transform(value: any, args: any): any {
if (!args) {return value;}
for(const text of args) {
var reText = new RegExp(text, 'gi');
value = value.replace(reText, "<mark>" + text + "</mark>");
//for your custom css
// value = value.replace(reText, "<span class='highlight-search-text'>" + text + "</span>");
}
return value;
}
}
Разделить вашу строку, чтобы создать массив строк.
var searchTerms = searchKey.split(' ');
использование:
<div [innetHTML]="result | highlight:searchTerms"></div>
Если вы хотите использовать пользовательский класс:
.highlight-search-text {
color: black;
font-weight: 600;
}
Всего наилучшего!