I'm using a custom directive and custom pipe to do currency formatting on text inputs. It works fine with any kind of direct user input (focus, blur, keydown). However I can't seem to capture the change event when the value is changed dynamically. I also can't find a reliable list of hostlistener events, and don't know of a way to capture any event coming to the input (and thus can't see what event, if any, is happening).
Dynamically, the value is being set with patchValue, and I've set emitEvent to true but this appears to do nothing (I assume it's true by default anyway):
myInput.patchValue({content: currentContent}, { emitEvent: true });
I could rewrite the currency formatting before the content value is set with patchValue, but this goes against reusability.
Here is my directive:
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();
    }
}
}
I've added the stackblitz here: https://stackblitz.com/edit/angular-tys9cy


@HostListener("change", ["$event.target.value", "$event"]) onChange(value, event) {}. In your pipe you should put the transformations intransform()method, it changes automatically.transform()method, but whatever event is happening when the value is dynamically changed is not being captured by hostlistener. I don't know if it has something to do with patchValue.