多くの研究の結果、このソリューションが完成しました。ハックのようなものですsince the Angular team doesn't recommend extending DefaultValueAccessor
しかし、それは自動的にそれぞれの入力を個別にマークすることなくすべての入力に動作します。
import { Directive, forwardRef, Renderer2, ElementRef, Input } from '@angular/core';
import { DefaultValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
export const VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => InputExtensionValueAccessor),
multi: true
};
@Directive({
selector: 'input:not([type]),input[type=text],input[type=password],input[type=email],input[type=tel],textarea',
host: {
'(input)': '_handleInput($event.target.value)',
'(blur)': 'onTouched()',
'(compositionstart)': '_compositionStart()',
'(compositionend)': '_compositionEnd($event.target.value)'
},
providers: [VALUE_ACCESSOR]
})
export class InputExtensionValueAccessor extends DefaultValueAccessor {
// HACK: Allows use of DefaultValueAccessor as base
// (https://github.com/angular/angular/issues/9146)
static decorators = null;
constructor(renderer: Renderer2, elementRef: ElementRef) {
super(renderer, elementRef, (null as any));
}
registerOnChange(fn: (_: any) => void): void {
super.registerOnChange(value => {
// Convert empty string from the view to null for the model
fn(value === '' ? null : value);
});
}
}
これは、角度4.4.5で私にとって素晴らしい仕事です。
ところで、フィールドにキーアップイベントを送信または追加する前に、自分のエンティティを消去できることがわかっています。しかし、私はそれのためだけにコードを書くことなくこれをしたいと思います。 – jobou
私はこれを自動的に行うものはないと思います。ただし、valueプロパティとinputイベントに対してngModelを別々のバインディングに分割し、値が空の文字列の場合はモデルをnullに設定することもできます。 –
内部的に 'input'を使用するコンポーネントを作成し、その内部にロジックを実装するのはどうですか?そうすれば、毎回それを書く必要はありません。 –