我正在创建一个自定义指令,假设重新格式化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;
}
}
}
答案 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);
}