我正在使用angular2,新形式的api。
我想要一个电话号码输入框,它会在用户输入时自动格式化。
例如用户输入:
12345678901
当他们输入可识别的电话号码时,它会变为
1 (234) 567-8901
我想出了如何在输入控件上添加指令,但我不知道如何将自己注入输入处理管道。
答案 0 :(得分:9)
您必须创建自己的指令,以此为例,它使用Phone.format进行转换,将原始数字存储在模型中,但将格式化的数字显示给用户:
import { Directive } from '@angular/core'
import { NgControl } from '@angular/forms'
import { Phone } from '../phone'
@Directive({
selector: '[ngModel][phone]',
host: {
'(ngModelChange)': 'onInputChange($event)',
'(blur)': 'onBlur($event)'
}
})
export class PhoneDirective {
constructor (control: NgControl) {
this.control = control
}
ngOnInit () {
let formatted = Phone.format(this.control.model)
setTimeout(() => this.control.valueAccessor.writeValue(formatted), 0)
}
onBlur () {
let val = this.control.model
let raw = val.replace(/\W/g, '')
let formatted = Phone.format(raw)
this.control.valueAccessor.writeValue(formatted)
this.control.viewToModelUpdate(raw)
}
onInputChange (val) {
let raw = val.replace(/\W/g, '')
if (val !== raw) this.control.viewToModelUpdate(raw)
}
}
答案 1 :(得分:0)
下面的指令将在您键入时格式化该值:
input
方法被触发(视图->模型,在AngularJS中又称为$ parser)。它可以确保视图获得格式化视图(通过render
方法),而模型则获得原始数值(通过propagateChange
方法)。 writeValue
方法(模型->视图,即AngularJS中的$ formatter)。这样可以确保视图获得格式化视图(通过render
方法)。format
方法包含格式化视图的逻辑。我们在那里需要一些额外的条件,以确保用户不仅可以输入字符,还可以将它们一个接一个地删除。要使用指令,请将其注册到模块中并将其链接到输入,例如:
<input appFormattedNumber formControlName= .../>
(我只用反应形式进行了测试)
import {Directive, ElementRef, forwardRef, HostListener, Renderer2} from '@angular/core';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
@Directive({
selector: '[appFormattedNumber]',
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => FormattedNumberDirective),
multi: true
}
]
})
export class FormattedNumberDirective implements ControlValueAccessor {
propagateChange;
constructor( private renderer: Renderer2, private element: ElementRef ) {}
@HostListener('input', [ '$event.target.value' ])
input( value ) {
const canonical = this.removeNonNumericCharacters(value);
const formatted = this.format(canonical);
this.render(formatted);
this.propagateChange(canonical);
}
writeValue( value: any ): void {
const canonical = this.removeNonNumericCharacters(value.toString());
const formatted = this.format(canonical);
this.render(formatted);
}
registerOnChange( fn: any ): void {
this.propagateChange = fn;
}
registerOnTouched(fn: any): void {}
setDisabledState(isDisabled: boolean): void {}
private removeNonNumericCharacters(value): string {
return value.replace(/\D/g, '');
}
private format(value): string {
if (value.length < 5) {
return value;
}
const int = value.substring(0, 1);
const areaCode = value.substring(1, 4);
const ext1 = value.substring(4, 7);
const ext2 = value.substring(7, 11);
const ext = ext2 ? ` ${ext1}-${ext2}` : `${ext1}`;
return `${int} (${areaCode}) ${ext}`;
}
private render(value) {
const element = this.element.nativeElement;
this.renderer.setProperty(element, 'value', value);
}
}