好的,這裏是一個如何處理用戶輸入的例子,它應該被設計處理。
測試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>
這比用管道,真正的更多的代碼,但是這是處理用戶輸入正確的方式,特別是當它應該以某種方式預處理。
你試圖用這個代碼解決什麼任務?我會說它不應該工作。如果你希望你的值在輸入中以某種特定的方式格式化,那麼你可能需要實現ControlValueAccessor ...但這只是我的猜測。請提供您想要實現的細節。 –
我正在編寫一個通用管道,用於刪除受限制的字符,更改大小寫,替換其他字符等。爲了簡化操作,我將問題簡化爲可能的最簡單情況來演示該錯誤 – TSG
這不是要走的路無論如何。如果您需要執行此類操作,則ControlValueAccessor是您最好的朋友。它將允許您直接訂閱輸入上的不同事件並在**值到達模型之前處理它們。例如,您可以通過在keydown事件中拒絕不需要的字符甚至在輸入之前拒絕它來糾正您的值。只要看看角度來源中的DefaultValueAccessor並添加一些創意思維。這不是火箭科學,儘管它需要你的一些代碼,但它肯定會是更好的方法。 –