如何动态格式化angular2中的输入元素?
How can I dynamically format an input element in angular2?
我正在使用 angular2,新形式 api。
我想要一个 phone 数字输入框,它会在用户输入时自动格式化。
例如用户类型:
12345678901
当他们输入可识别的 phone 数字时,它会变为
1 (234) 567-8901
我想出了如何将指令添加到输入控件上,但我不知道如何将自己注入到输入处理管道中。
你必须创建自己的指令,以这个为例,它使用 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)
}
}
下面的指令将在您键入时格式化值:
- 当用户输入值时触发
input
方法(视图 -> 模型,又名 AngularJS 中的 $parser)。它确保视图获得格式化视图(通过 render
方法),而模型获得原始数值(通过 propagateChange
方法)。
- 当模型更新时触发
writeValue
方法(模型 -> 视图,在 AngularJS 中又名 $formatter)。它确保视图获得格式化视图(通过 render
方法)。
format
方法包含格式化视图的逻辑。我们需要一些额外的条件来确保用户不仅可以输入字符,还可以一个一个地删除它们。
要使用该指令将其注册到模块中并link将其输入到输入中,例如:
<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);
}
}
我正在使用 angular2,新形式 api。
我想要一个 phone 数字输入框,它会在用户输入时自动格式化。
例如用户类型:
12345678901
当他们输入可识别的 phone 数字时,它会变为
1 (234) 567-8901
我想出了如何将指令添加到输入控件上,但我不知道如何将自己注入到输入处理管道中。
你必须创建自己的指令,以这个为例,它使用 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)
}
}
下面的指令将在您键入时格式化值:
- 当用户输入值时触发
input
方法(视图 -> 模型,又名 AngularJS 中的 $parser)。它确保视图获得格式化视图(通过render
方法),而模型获得原始数值(通过propagateChange
方法)。 - 当模型更新时触发
writeValue
方法(模型 -> 视图,在 AngularJS 中又名 $formatter)。它确保视图获得格式化视图(通过render
方法)。 format
方法包含格式化视图的逻辑。我们需要一些额外的条件来确保用户不仅可以输入字符,还可以一个一个地删除它们。
要使用该指令将其注册到模块中并link将其输入到输入中,例如:
<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);
}
}