0

如何在輸入中顯示轉換後的值(例如「1(234)567-890」),還沒有轉換值('1234567890')?如何屏蔽自定義控件中的值

是否可以爲maskInputElmaskInput分隔值?

我的模板:

<input #maskInputEl class="spacer" [type]="type" 
    [formControl]="maskInput"/> 

和自定義組件:

export class MaskInputComponent implements ControlValueAccessor, OnInit, OnDestroy { 
    @ViewChild('maskInputEl') public maskInputEl: ElementRef; 

    @Input() public mask: any[]; 

    public maskInput = new FormControl(); 

    private _oldValue: string = ''; 

    public ngOnInit(): void { 
     this.maskInput.valueChanges 
      .subscribe((value: string) => { 
        let valid = this.isValidValueByMask(value, this.mask); 
        if (valid) { 
         this._oldValue = value; 
        } else { 
         value = this._oldValue; 
        } 

        this._onChangeCallback(value); 
        this.onChange.emit(value); 

        this.maskInputEl.nativeElement.value = value; 
       }, 
       (err) => console.warn(err) 
      ); 
    } 

    public toggleActive(value) { 
     // 
    } 

    public registerOnChange(fn: any): void { 
     this._onChangeCallback = fn; 
    } 

    public registerOnTouched(fn: any): void { 
     this._onTouchedCallback = fn; 
    } 

    public _onChangeCallback: Function = (_: any) => { 
     // 
    } 

    public _onTouchedCallback: Function = (_: any) => { 
     // 
    } 

    public makeActive() { 
     this.maskInputEl.nativeElement.focus(); 
    } 

    public writeValue(value: string): void { 
     this.maskInput.setValue(value); 
    } 

    public ngOnDestroy(): void { 
     // 
    } 

    private isValidValueByMask(value: string, mask: RegExp[]): boolean { 
     // 
    } 
} 

回答

1

是的,這是可能的。我爲自己的項目做了類似的事情,我想創建一個返回價值爲美分的MoneyFieldComponent,但允許用戶以美元和美分輸入他們的貨幣價值。

基本概念是您的組件必須存儲原始值,但是,在文本字段中顯示格式化的值。另外,當用戶與文本字段交互時,用原始值更新組件的「內部值」。

請注意,你不應該使用ngModel來更新你的文本字段 - ngModel有一些異步行爲,在這些場景中發揮破壞性 - 你可以使用原始javascript(或在我的情況下,我使用FormControl)完成相同的操作。

樣品:

@Component({ 
    selector: 'ec-money-field', 
    template: ` 
     <md-input-container *ngIf="editMode"> 
      <input #input mdInput class="value" type="text" 
       (input)="updateInnerValue(input.value)" 
       (blur)="formatTextValue()" 
       [formControl]="control" /> 
     </md-input-container> 
    `, 
    providers: [ 
    {provide: NG_VALUE_ACCESSOR, multi: true, useExisting: forwardRef(() => MoneyFieldComponent)}, 
    ] 
}) 
export class MoneyFieldComponent implements OnInit, ControlValueAccessor { 

    private valueInCents = 0; 
    control = new FormControl(0); 

    private onChange: Function = (_: any) => {}; 
    private onTouch: Function = (_: any) => {}; 

    constructor() { } 

    @Input() 
    get value(): number { 
    return this.valueInCents; 
    }; 

    // if you update the component by using the value property, 
    // propagate that change to the text field  
    set value(newValueInCents: number) { 
    this.valueInCents = newValueInCents; 
    this.control.setValue(centsToDollars(newValueInCents)); 
    } 

    ngOnInit() { 
    } 

    // convert the masked value - i.e. what the user types 
    // into the actual numerical value that will be stored 
    // You'll have to provide your own conversion function 
    // to convert the user typing 1(855) 555 1234 to 1865551234 
    updateInnerValue(dollarValueString: string) { 
    this.valueInCents = dollarsToCents(dollarValueString); 
    this.onChange(this.valueInCents); 
    } 

    formatTextValue() { 
    this.value = this.value; 
    } 

    writeValue(newValue: number): void { 
    this.value = newValue; 
    } 

    registerOnChange(fn: any): void { 
    this.onChange = fn; 
    } 

    registerOnTouched(fn: any): void { 
    this.onTouch = fn; 
    } 
} 

注意,以上是組件的簡化版本。 The full version can be found on Github.

+0

我需要相反的,用戶輸入清除數據和輸入轉換數據與掩碼 – Zverit

+0

但你仍然存儲'清除數據'的權利?如果是這樣,那麼它就是用戶鍵入後的基本概念 - ,用格式化的值更新formField,但將實際值存儲在組件中。如果您僅將formField更新爲blur上的格式化值,則更容易實現 - 試圖在每個輸入事件上執行此操作似乎不能提供良好的用戶體驗 - 但是如果您嘗試提供輸入掩碼,那麼你沒有選擇,只能更新輸入事件的格式化值。如果遇到問題,我可以更新示例代碼 – snorkpete