加载数据时的Angular Material输入框事件

时间:2017-10-09 22:15:40

标签: angular angular-material2

我正在创建一个自定义指令,假设重新格式化md-input中的文本。在我的指令  ngOnInit和@HostListener中('模糊',[' $ event.target.value'])我有一个逻辑来重新格式化输入的文本用户。它正在工作,除非数据从api调用绑定。我想知道当angular更新数据时会发生什么事件被触发,所以我可以在我的指令中监听它并为我的数据激发我的格式逻辑。

更新1: 添加了代码以清理内容

        <input type="text"
               mdInput
               [(ngModel)]="item.Price"
               appMyPriceFormatter
               placeholder="Price"
               tabindex="5"
               [disabled]="disableInputs">

指令代码:

    import {Directive, ElementRef, HostListener, OnInit} from '@angular/core';
    import {CurrencyPipe} from '@angular/common';

    @Directive({
      selector: '[appMyPriceFormatter]'
    })
    export class MyPriceFormatterDirective implements OnInit {

      private el: HTMLInputElement;

      constructor(private elementRef: ElementRef,
                  private currencyPipe: CurrencyPipe) {
        this.el = this.elementRef.nativeElement;
      }

      ngOnInit() {
        if ((this.el.value !== null) && (this.el.value.trim() !== '')) {
          this.el.value = this.currencyPipe.transform(this.el.value, 'USD', true, '1.5-5');
        } else {
          this.el.value = null;
        }
      }

      @HostListener('focus', ['$event.target.value'])
      onFocus(value) {
        this.el.value = value.replace(/[^\d\-\.]/g, '');
      }

      @HostListener('blur', ['$event.target.value'])
      onBlur(value) {
        if ((value !== null) && (value.trim() !== '')) {
          this.el.value = this.currencyPipe.transform(value, 'USD', true, '1.5-5');
        } else {
          this.el.value = null;
        }
      }
    }

3 个答案:

答案 0 :(得分:0)

我认为如果你在你的指令中监听ngModelChange事件,你应该能够异步地获取输入字段发生的变化。

所以在你的指令中,

@HostListener('ngModelChange', ['$event'])
onInputFieldChange(value) {
  // logic for handling the change
}

有关ngModelChange事件的更多信息,请参阅this

答案 1 :(得分:0)

我只需将ngOnInit()更改为ngOnChange(),因为数据是异步到达的。

或者你可能不需要指令Ref:SO: Using Pipes within ngModel on INPUT Elements in Angular2-View(虽然我注意到焦点上的去货币化)。

<input type="text"
  mdInput
  [ngModel]="item.Price | currency"
  (ngModelChange)="item.Price=$event"
  placeholder="Price"
  tabindex="5"
  [disabled]="disableInputs">

设置一个小提琴进行测试会很有趣。

这是一个有效的Plunker概念,

@Pipe({ name: 'myPipe'})
export class MyPipe implements PipeTransform{
  transform(value, focused) {
    return (focused ? '' : '$') + 
      value.replace(/[^\d\-\.]/g, '')
  } 
}

@Component({
  selector: 'my-app',
  template: `<h1>Input with Currency Pipe</h1>
    <input type="text"
      [ngModel]="value | myPipe:focused"
      (ngModelChange)="value=$event"
      placeholder="Price"
      tabindex="5"
      [disabled]="disableInputs"
      (focus)="focused = true"
      (blur)="focused = false"
    >
  `
})
export class App { 
  value = '3.01';
  focused = false;
}

我觉得必须有办法摆脱焦点变量。

答案 2 :(得分:0)

显然我可以使用ngModel的货币来实现这一点,并在ngModelChange的处理程序中做一些棘手的事情,但是这意味着在每个字段的每个页面上我都需要有一个单独的函数,依此类推。除此之外,我使用货币管道只是为了现实的例子,我做的事情有点棘手。考虑到这一点,我不希望这种逻辑扩展到多个功能和组件,所以我最终进一步调整了我的指令。

在挖掘生命周期事件后,看起来像ngDoCheck(https://angular.io/guide/lifecycle-hooks)就可以了。我需要注意的唯一部分是递归保护和防止在用户输入时格式化它,所以我最终会得到类似的东西:

ngDoCheck() {
    if (this.focused) {
        return;
    }

    this.el.value = this.formatValue(this.el.value);
}