如何在动态更新时检测输入的值变化(Angular 6)

  • 本文关键字:变化 Angular 动态 更新 angular
  • 更新时间 :
  • 英文 :


我正在使用自定义指令和自定义管道对文本输入进行货币格式化。它适用于任何类型的直接用户输入(焦点、模糊、键控(。但是,当值动态更改时,我似乎无法捕获更改事件。我也找不到可靠的主机侦听器事件列表,并且不知道捕获进入输入的任何事件的方法(因此无法看到正在发生的事件(如果有的话(。

动态地,该值是使用 patchValue 设置的,我已经将 emitEvent 设置为 true,但这似乎没有任何作用(无论如何,我假设默认情况下它是真的(:

myInput.patchValue({content: currentContent}, { emitEvent: true });

我可以在使用 patchValue 设置内容值之前重写货币格式,但这违背了可重用性。

这是我的指示:

import { Directive, HostListener, ElementRef, OnInit } from '@angular/core';
import { CurrencyPipe } from '../pipes/currency.pipe';
@Directive({
selector: '[appCurrency]'
})
export class CurrencyDirective implements OnInit {
constructor(
private elementRef:ElementRef,
private formatcurrencypipe:CurrencyPipe
) { }
ngOnInit(){
//this.elementRef.nativeElement.value = this.formatcurrencypipe.transform(this.elementRef.nativeElement.value);
}
@HostListener("change", ["$event.target.value", "$event"]) onChange(value, event) {
//this.elementRef.nativeElement.value = this.formatcurrencypipe.parse(value);
}
@HostListener("valueChange", ["$event.target.value", "$event"]) onValueChange(value, event) {
console.log('in onValueChange');
//doesn't trigger when the value is changed dynamically
}
@HostListener("focus",["$event.target.value","$event"]) onFocus(value,event) {
console.log('in focus');
this.elementRef.nativeElement.value = this.formatcurrencypipe.parse(value);
if(event.which == 9)
{
return false;
}
this.elementRef.nativeElement.select();
}
@HostListener("blur", ["$event.target.value"]) onBlur(value) {
console.log('in blur');
this.elementRef.nativeElement.value = this.formatcurrencypipe.transform(value);
}
@HostListener('keydown', ['$event']) onKeyDown(event) {
let e = <KeyboardEvent> event;
console.log('e.keyCode: ', e.keyCode, e.ctrlKey, e.metaKey);
//delete, backspace, tab, escape, enter, decimal, period, arrow left, arrow right
if ([46, 8, 9, 27, 13, 110, 190, 37, 39].indexOf(e.keyCode) !== -1
|| (e.keyCode === 65 && (e.ctrlKey || e.metaKey)) //CTRL + A
|| (e.keyCode === 67 && (e.ctrlKey || e.metaKey)) //CTRL + C
|| (e.keyCode === 86 && (e.ctrlKey || e.metaKey)) //CTRL + V
|| (e.keyCode === 88 && (e.ctrlKey || e.metaKey))) {  //CTRL + X
//do nothing
return;
}
// Check for number
if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) {
e.preventDefault();
}
}
}

我在这里添加了堆栈闪电战:https://stackblitz.com/edit/angular-tys9cy

反应式表单实例(如FormGroupFormControl(具有返回发出最新值的observablevalueChanges方法。它不会发出 DOM 事件。
溶液

而不是valueChange绑定到将在两个事件上触发的ngModelChange,即当 formControl 在视图中或通过模型更新时。

@HostListener("ngModelChange", [ "$event"]) onNgModelChange(value) {
console.log(value)
this.elementRef.nativeElement.value = this.formatcurrencypipe.transform(value);
}

Working StackBlitz

基于@vikas答案,我进行了修改,以便它仅在动态设置值时更新ngModelChange,而不是在用户编辑时更新(因为ngModelChange对于我需要的来说太包容了(:

@HostListener("ngModelChange", [ "$event"]) onNgModelChange(value) {
//when value changes dynamically
if (this.elementRef.nativeElement.dataset.isfocused == 'false') {
console.log('is not focused');
this.elementRef.nativeElement.value = this.formatcurrencypipe.transform(value);
} else {
console.log('is focused');
}
}
@HostListener("focus",["$event.target.value","$event"]) onFocus(value,event) {
this.elementRef.nativeElement.dataset.isfocused = true;
console.log('isfocused: ', this.elementRef.nativeElement.dataset);
this.elementRef.nativeElement.value = this.formatcurrencypipe.parse(value);
if(event.which == 9)
{
return false;
}
this.elementRef.nativeElement.select();
}
@HostListener("blur", ["$event.target.value"]) onBlur(value) {
this.elementRef.nativeElement.dataset.isfocused = false;
this.elementRef.nativeElement.value = this.formatcurrencypipe.transform(value);
}

和输入:

<input appCurrency data-isfocused="false" type="text" class="form-control number" formControlName="myInput" />

使用数据属性似乎非常没有角度:-(

最新更新