我正在尝试使用mat-autocomplete
来实现与以下示例类似的过滤器;
所以我试图实现这个功能,这样当用户开始输入交易时,他们正在寻找基于字符串中任何位置的部分字符串匹配的过滤器,并在选项中突出显示。
我现在有我的.html
<mat-form-field class="form-group special-input">
<input type="text" placeholder="Select a trade" aria-label="Select a trade" matInput [formControl]="categoriesCtrl" [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete" md-menu-class="autocomplete">
<mat-option *ngFor="let option of filteredOptions | async" [value]="option.name">
{{ option.name }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
我的.ts是
categoriesCtrl: FormControl;
filteredOptions: Observable<ICategory[]>;
options: ICategory[];
categorySubscription: Subscription;
constructor(fb: FormBuilder, private router: Router, private service: SearchService, private http: Http) {
this.categoriesCtrl = new FormControl();
}
ngOnInit() {
this.categorySubscription = this.service.getCategories().subscribe((categories: ICategory[]) => {
this.options = categories;
this.filteredOptions = this.categoriesCtrl.valueChanges
.pipe(
startWith(''),
map(options => options ? this.filter(options) : this.options.slice())
);
});
}
ngOnDestroy() {
this.categorySubscription.unsubscribe();
}
filter(val: string): ICategory[] {
return this.options.filter(x =>
x.name.toUpperCase().indexOf(val.toUpperCase()) !== -1);
}
ICategory
是一个基本界面。
export interface ICategory {
value: number;
name: string;
}
服务getCategories()只返回api中的所有类别。
该代码目前正在按照此示例工作和构建;
Angular Material mat-autocomplete example
我想在选项字符串中添加突出显示术语的效果?这有可能吗?
答案 0 :(得分:14)
只要用户输入过滤器中的内容,您就可以使用自定义管道突出显示部分匹配。
@Pipe({ name: 'highlight' })
export class HighlightPipe implements PipeTransform {
transform(text: string, search): string {
const pattern = search
.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")
.split(' ')
.filter(t => t.length > 0)
.join('|');
const regex = new RegExp(pattern, 'gi');
return search ? text.replace(regex, match => `<b>${match}</b>`) : text;
}
}
答案 1 :(得分:0)
要解决未定义的问题,您应该只检查搜索字符串是否存在,有时您在控件上没有:
export class HighlightPipe implements PipeTransform {
transform(text: string, search): string {
if (search && text && typeof search === 'string' && typeof text === 'string') {
const pattern = search
.replace(/[\-\[\]\/{}()*x+?.\\^$|]/g, '\\$&')
.split(' ')
.filter(t => t.length > 0)
.join('|');
const regex = new RegExp(pattern, 'gi');
return search ? text.replace(regex, match => `<strong>${match}</strong>`) : text;
}
return text;
}
}
另请注意,一些正则表达式已被精简,因为某些转义不是必需的。
最后在 HTML 中,您现在应该使用 [innerHTML] 而不是管道对象文本:
<mat-option [innerHTML]="optionText | highlight: searchValue"></mat-option>