我创建了一个简单的管道,我将其应用于文本输入。正则表达式工作 - 但有些奇怪。控制台日志CORRECTLY显示新值(删除非字母数字),但在浏览器中输入字段不会更新,直到我输入一个好的字符。因此输入“123 !!!! A”将显示感叹号,直到输入A然后它们消失。为什么呢?
我使用这样的管道:
<input type="text" class="form-control" [ngModel]="name | inputFormat" (ngModelChange)="name=$event">
并且管道是
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'inputFormat'
})
export class InputFormatPipe implements PipeTransform {
transform(value: any): any {
value = value.replace(/[^a-z0-9]/gi, '');
console.log('new value: '+value);
return value;
}
}
我怀疑更改检测无效 - 但不确定如何解决此问题。
答案 0 :(得分:0)
好的,这是一个如何在设计处理用户输入的地方处理用户输入的示例。
<强>测试input.directive.ts 强>
import { Directive, ElementRef, Renderer2, forwardRef, HostListener } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
export const TEST_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => TestInputDirective),
multi: true
};
@Directive({
selector: 'input[appTestInput]',
providers: [TEST_VALUE_ACCESSOR]
})
export class TestInputDirective implements ControlValueAccessor {
onChange = (_: any) => { };
onTouched = () => { };
constructor(private _renderer: Renderer2, private _elementRef: ElementRef) { }
// this gets called when the value gets changed from the code outside
writeValue(value: any): void {
const normalizedValue = value == null ? '' : value;
this._renderer.setProperty(this._elementRef.nativeElement, 'value', normalizedValue);
}
registerOnChange(fn: (_: any) => void): void { this.onChange = fn; }
registerOnTouched(fn: () => void): void { this.onTouched = fn; }
setDisabledState(isDisabled: boolean): void {
this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
}
// just as an example - let's make this field accept only numbers
@HostListener('keydown', ['$event'])
_handleKeyDown($event: KeyboardEvent): void {
if (($event.keyCode < 48 || $event.keyCode > 57) && $event.keyCode !== 8) {
// not number or backspace, killing event
$event.preventDefault();
$event.stopPropagation();
}
}
@HostListener('input', ['$event'])
_handleInput($event: KeyboardEvent): void {
// this is what we should call to inform others that our value has changed
this.onChange((<any>$event.target).value);
}
}
只需将此指令声明添加到您的模块:
<强> 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 { TestInputDirective } from './test-input.directive';
@NgModule({
declarations: [
AppComponent,
TestInputDirective // <-- you'll need this
],
imports: [
BrowserModule,
FormsModule // <-- and this
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
然后您可以在模板中使用它:
<强> app.component.html 强>
<input type="text" appTestInput [(ngModel)]="name">
<div>{{name}}</div>
这比使用管道更多的代码,是的,但是这是处理用户输入的正确方法,尤其是当它应该以某种方式进行预处理时。