2017-10-09 75 views
1

我正在创建一个自定义指令,该指令假定重新格式化MD输入中的文本。在我的指令的ngOnInit和@HostListener('模糊',['$ event.target.value'])我有一个逻辑来重新格式化用户输入的文本。除了当数据从api调用绑定时,它正在工作。我想知道当角度更新数据时会发生什么事件,所以我可以在我的指令中侦听它并为我的数据激发我的格式逻辑。加载数据时的角度材质输入框事件

更新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; 
     } 
     } 
    } 
+0

你的意思是它的工作与静态数据,但不与异步数据? –

+0

你能显示你的输入模板标签吗? – amal

+0

@RichardMatsen,是的。 – AlexanderM

回答

0

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

在挖掘生命周期事件后,它看起来像ngDoCheck(https://angular.io/guide/lifecycle-hooks)将会有所斩获。我需要注意的唯一部分是对格式化当用户敲击键盘,因此我结束了类似的递归保护和保护:

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

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

我认为,如果你听你的指令ngModelChange事件,你应该能够以异步获取输入字段发生的更改。

所以你的指令中,

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

this更多的ngModelChange事件。

+0

这不是在初始数据加载时被触发,而是因为其他任何不是我想要的更改而被触发 – AlexanderM

+0

您可以在哪里更新输入元素的值api电话的数据? – amal

0

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

或者您可能不需要指令参考: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; 
} 

我有一种感觉,一定要有摆脱聚焦变量,以及一种方式。