简体   繁体   中英

ngModel setting value after directive

I have the following problem:

I have an phone number input field like this:

电话号码输入

I want to mask the text like 55-5555-5555 so I have created a directive:

import { Directive, HostListener } from '@angular/core';
import { NgControl } from '@angular/forms';

@Directive({
  selector: '[appPhoneNumber]'
})
export class PhoneNumberDirective {

 constructor(public ngControl: NgControl) { }

  ngOnInit() {
    this.windowReady(this.ngControl.model);

  }

  windowReady(value) {
    this.onInputChange(value, false);
  }

  @HostListener('ngModelChange', ['$event'])
  onModelChange(event) {
    this.onInputChange(event, false);
  }

  @HostListener('keydown.backspace', ['$event'])
  keydownBackspace(event) {
    this.onInputChange(event.target.value, true);
  }

  onInputChange(event, backspace) {
    let newVal = event.replace(/\D/g, '');
    if (backspace && newVal.length <= 6) {
      newVal = newVal.substring(0, newVal.length - 1);
    }
    if (newVal.length === 0) {
      newVal = '';
    } else if (newVal.length <= 2) {
      newVal = newVal.replace(/^(\d{0,3})/, '$1');
    } else if (newVal.length <= 6) {
      newVal = newVal.replace(/^(\d{0,2})(\d{0,4})/, '$1-$2');
    } else if (newVal.length <= 10) {
      newVal = newVal.replace(/^(\d{0,2})(\d{0,4})(\d{0,4})/, '$1-$2-$3');
    } else {
      newVal = newVal.substring(0, 10);
      newVal = newVal.replace(/^(\d{0,2})(\d{0,4})(\d{0,4})/, '$1-$2-$3');
    }
    console.log("New value is: " + newVal);
    this.ngControl.valueAccessor.writeValue(newVal);
  }
}

And here is the input field:

<mat-form-field style="width: 75%;">
  <input matInput appPhoneNumber placeholder="Telefono" [(ngModel)]="person.numero_telefono">
</mat-form-field>

As you can see, the input has an ngModel for getting and setting the value, the problem I am facing right now is when the input first appear and the ngModel has a value, the field displays the text like:

5555555555

Instead of:

55-5555-5555

My theory right now is that the directive is setting the value:

this.ngControl.valueAccessor.writeValue(newVal);

Before the input itself:

<input matInput appPhoneNumber placeholder="Telefono" [(ngModel)]="person.numero_telefono">

So when the input set the value, it takes the value without the mask and overrides the text set by the directive.

Does anyone know how to call the directive after the ngModel or something that help me?

I believe you want a pipe, not a directive. If you take a look at this post it talks about how to use a pipe with an ngModel Using Pipes within ngModel on INPUT Elements in Angular

ng-mask might be what you are looking for.

<input matInput appPhoneNumber placeholder="Telefono" [(ngModel)]="person.numero_telefono" mask='55-5555-5555'>

Here is the link for further information ng-mask

The issue is not with [(ngModel)] or Input control. The actual cause of this issue is matInput directive. Just remove matInput and check.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM