Возможно ли использовать форматировщик трубы Angular внутри элемента управления textbox при редактировании? - PullRequest
2 голосов
/ 10 марта 2019

Я объявил формат для разделения больших чисел на группы из трех цифр и часто использую его следующим образом.

<div>Huge number: {{ i_am_huge | make_threesome }}</div>

Теперь есть запрос на соответствующую функциональность, но реализованный в элементе управления вводом, подобном этому.

<input id="numeroUno"
       type="text">

Подход, который я могу придумать, состоит в том, чтобы прослушать набор текста и для каждого ключа выполнить переформатирование содержимого поля следующим образом.

<input id="numeroUno"
       type="text"
       (keyup)="formatify">

Однако, хотя этот подход будет работать, я не перестаю удивляться, если это слишком много вопросов и ответов, поэтому, прежде чем я соберу всю контрольную фауну вокруг этой парадигмы, я хотел бы получить больше информации.

Обычный поиск в Google не дал мне много. Тем не менее, дать довольно необычный характер требования, это может быть трудно найти.

Предположение на данный момент состоит в том, что управление вводом не должно использоваться таким образом, что объясняет неуклюжесть моего подхода.

Ответы [ 2 ]

2 голосов
/ 10 марта 2019

Используйте директиву. В stackblitz вы можете увидеть, как работает.

Директива хранит в переменной «value» строку без пробелов. Каждое изменение происходит (я использую @HotListener (input)), чтобы получить позицию курсора, получить значение элемента, удалить пробелы, сформировать число и поместить курсор в позицию

@Directive({ selector: "[testPipe]" })
export class TestPipe  implements OnInit {

  private el: HTMLInputElement;
  private value: any;
  constructor(@Optional() private ngControl:NgControl,
                private elementRef: ElementRef) {
    this.el = this.elementRef.nativeElement;
  }
  @HostListener("input", ["$event.target.value"])
  onInput() {
    let pos = this.el.selectionStart; //get the position of the cursor
    this.value = this.el.value.replace(/ /gi, ""); //store the value without spaces
    if (this.value.length%3==1) //If we must add an extra space
      pos++;
    //Yes, it's a "bizarro" way to separate in group of three 
    this.el.value=this.value.match(/(.+?)(?=(.{3})+(?!.)|$)/g).join(' ');
    //this.el.value=this.value.match(/(\d+?)(?=(\d{3})+(?!\d)|$)/g).join(' ');
    //Finally give the position of cursor
    this.el.selectionStart = this.el.selectionEnd = pos;
    if (this.ngControl)
        this.ngControl.control.setValue(this.el.value,{emit:false})

  }
  ngOnInit()
  {
    this.value = this.el.value.replace(/ /gi, "");
    this.el.value=this.value.match(/(.+?)(?=(.{3})+(?!.)|$)/g).join(' ');
//  this.el.value=this.value.match(/(\d+?)(?=(\d{3})+(?!\d)|$)/g).join(' ');
    if (this.ngControl)
        this.ngControl.control.setValue(this.el.value,{emit:false})

  }
}

Обновление Я добавляю @Optional () ngControl: NgControl в конструктор, поэтому, если директива применяется к ngControl (входные данные принадлежат formGroup или имеет [(ngModel)], измените значение тоже

1 голос
/ 10 марта 2019

Я думаю, вам лучше использовать директиву (attribute) здесь.Вы можете использовать директивы для целей проверки, так почему бы не использовать их для форматирования в ваших полях ввода (на самом деле, в данный момент я пытаюсь сделать что-то подобное в моем собственном проекте).

В принципе это будет выглядеть примерно так(пример из угловых документов):

import { Directive, ElementRef, HostListener, Input } from '@angular/core';

@Directive({
  selector: '[appHighlight]'
})
export class HighlightDirective {

  constructor(private el: ElementRef) { }

  @Input('appHighlight') highlightColor: string;

  @HostListener('mouseenter') onMouseEnter() {
    this.highlight(this.highlightColor || 'red');
  }

  @HostListener('mouseleave') onMouseLeave() {
    this.highlight(null);
  }

  private highlight(color: string) {
    this.el.nativeElement.style.backgroundColor = color;
  }
}

Таким образом, вы можете манипулировать значениями внутри поля ввода и прослушивать события типа click.

Еще одна вещь, которую вы должны сделать, прежде чем она заработает: добавьте директиву (очень похожую на [ngStyle] или [ngClass]) к вашему вводу, поданному через [your-directives-name].Посмотрите на следующий фрагмент кода и как это делается:

<h1>My First Attribute Directive</h1>

<h4>Pick a highlight color</h4>
<div>
  <input type="radio" name="colors" (click)="color='lightgreen'">Green
  <input type="radio" name="colors" (click)="color='yellow'">Yellow
  <input type="radio" name="colors" (click)="color='cyan'">Cyan
</div>
<p [appHighlight]="color">Highlight me!</p>
...