Tôi vừa mới hình thành giải pháp này sau nhiều nghiên cứu. Đó là loại hack since the Angular team doesn't recommend extending DefaultValueAccessor
, nhưng nó tự động hoạt động cho mọi đầu vào mà không cần phải đánh dấu từng cái một.
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);
});
}
}
Điều này phù hợp với tôi trên Angular 4.4.5.
Nguồn
2017-10-19 17:24:31
Nhân tiện, tôi biết rằng tôi có thể làm sạch pháp nhân của mình trước khi gửi hoặc thêm sự kiện khóa trên trường của tôi. Nhưng tôi muốn làm điều này mà không cần viết bất kỳ mã nào chỉ cho điều đó. – jobou
Tôi không nghĩ rằng có bất cứ điều gì mà sẽ làm điều này tự động. Tuy nhiên, bạn có thể chia ngModel thành các ràng buộc riêng biệt cho thuộc tính giá trị và sự kiện đầu vào và chỉ cần đặt mô hình thành null nếu giá trị là chuỗi rỗng. –
Điều gì về việc tạo một thành phần sử dụng nội bộ 'đầu vào' và thực hiện logic bên trong nó? Bằng cách đó bạn sẽ không cần phải viết nó mọi lúc. –