對(duì)于輸入文本框,經(jīng)常會(huì)有過(guò)濾特殊字符的要求,這個(gè)可以封裝指令來(lái)解決。
import { Directive, ElementRef, HostListener } from '@angular/core';
import { NgControl } from '@angular/forms';
@Directive({
selector: '[appFilterSpecialChar]'
})
export class FilterSpecialCharDirective {
private specialStringRegexp = /[`~!@#$%^&*()+|{}\[\]:;'"<>?,.\/\\]/g;
private isComposing = false;
private curVal:any;
constructor(private ngControl: NgControl,private el:ElementRef) {}
ngOnInit(){
const ctrl = this.ngControl.control;
if(!ctrl)
return;
this.el.nativeElement.addEventListener('compositionstart',()=>{
this.isComposing = true;
});
this.el.nativeElement.addEventListener('compositionend',()=>{
this.isComposing = false;
});
ctrl.valueChanges.subscribe(v=>{
if(!v || this.isComposing){
return;
}
console.log('過(guò)濾前的字符>>>',v);
this.curVal = v;
this.cleanValue();
});
}
private cleanValue(){
const ctrl = this.ngControl.control;
if(ctrl){
const filteredValue = this.curVal.replace(this.specialStringRegexp,'');
console.log('過(guò)濾后的字符>>>',filteredValue);
ctrl.setValue(filteredValue, { emitEvent: false });
}
}
ngOnDestroy(){
this.el.nativeElement.removeEventListener('compositionstart',()=>{
this.isComposing = true;
});
this.el.nativeElement.removeEventListener('compositionend',()=>{
this.isComposing = false;
this.cleanValue();
});
}
//這樣寫會(huì)出現(xiàn)打漢字時(shí),來(lái)不及拼出漢字就把拼音顯示上去了
// @HostListener('input', ['$event'])
// onInput(event: Event): void {
// console.log('filter spec>>>',event);
// const input = event.target as HTMLInputElement;
// const filteredValue = input.value.replace(this.specialStringRegexp, '');
// this.ngControl.control?.setValue(filteredValue, { emitEvent: false });
// }
}
指令主要用于封裝對(duì)DOM的操作和行為,它們可以被附加到HTML元素、組件或?qū)傩陨?,用于低?jí)別的DOM操作,如樣式應(yīng)用、事件監(jiān)聽、屬性綁定等。
這里需要注意的是,如果直接監(jiān)聽input輸入行為,會(huì)導(dǎo)致拼音輸入法有問(wèn)題,用戶來(lái)不及拼出漢字就回顯了,所以得用到compositionstart和compositionend事件。
當(dāng)用戶開始輸入拼音時(shí),觸發(fā)compositionstart事件,此時(shí)可以設(shè)置一個(gè)狀態(tài)標(biāo)記表示正在輸入法組合中。
當(dāng)用戶完成輸入漢字后,觸發(fā)compositionend事件,此時(shí)可以取消狀態(tài)標(biāo)記,并進(jìn)行相應(yīng)的處理。
然后在模塊里面導(dǎo)入:
import { FilterSpecialCharDirective } from '../../directive/filter-special-char.directive';
import { SuffixInputComponent } from './suffix-input/suffix-input.component';
@NgModule({
declarations: [
FilterSpecialCharDirective,
SuffixInputComponent
],
imports: [
...
],
exports: [],
})
export class TestModule {}
這樣就可以在前端使用了:
<input
appFilterSpecialChar
type="text"
nz-input
[placeholder]="text"
[(ngModel)]="keyword"
(keyup.enter)="onSearch()"
(ngModelChange)="trimValue($event)"
/>