编辑时是否可以在文本框控件中使用Angular的管道格式化程序?

时间:2019-03-10 09:55:13

标签: html angular input format

我已经声明了一种将大数字分成三位数的格式,并经常这样使用。

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

现在,存在对相应功能的请求,但需要在这样的输入控件中实现。

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

我能想到的方法是听打字,并为每个键重新格式化盒子的内容。

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

但是,尽管这种方法行得通,但我不禁怀疑它是否涉及过多的Q&D,因此,在围绕这种范例构建整个控制动物群之前,我想了解更多信息。

通常的谷歌搜索并没有给我太多。但是,由于要求的性质非常特殊,因此可能很难找到。

此时的假设是,不应以这种方式使用输入控制,这说明了我方法的笨拙。

2 个答案:

答案 0 :(得分:2)

使用指令。在stackblitz中,您可以看到工作原理。

指令在变量“值”中存储不带空格的字符串。每次发生更改时(我使用@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 :(得分:1)

我认为您应该在此处使用(attribute) directive。您可以将指令用于验证目的,所以为什么不使用它在输入字段中进行格式化(实际上,目前正在尝试在我自己的项目中执行类似的操作)。

基本上看起来像这样(例如来自角度文档的示例):

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>