'Angular2 - Directive not updating model
I have a directive on an html input box that holds numeric values. When a user pastes a number into the textbox I have a directive that "cleans" the number (strips commas, dollar signs, etc). The cleaning code seems to work fine however my model is not being updated with the cleaned value even though the text box is showing my cleaned value.
How do I get my model updated with the new value?
Here is a stripped down example:
app.ts
@Component({
selector : 'my-app',
template : `
<div>
<br/>
<br/>
<p>Stack Overflow person - give focus to text box and then lose focus by clicking elsewhere in the screen. <br/>The model is not updated.</p>
<br/>Model value: {{ balanceAmount }}
<br/>
<br/>
<input type="text" [(ngModel)]="balanceAmount" myCurrencyFormatter /><br/>
</div>
`,
})
export class App {
name:string;
constructor(private mycurpipe: MyCurrencyPipe) {
this.balanceAmount = 1234567.89;
}
}
Currency-Formatter-Directive.ts
@Directive({ selector: "[myCurrencyFormatter]" })
export class MyCurrencyFormatterDirective implements OnInit {
private el: any;
constructor(
private elementRef: ElementRef,
private currencyPipe: MyCurrencyPipe
) {
this.el = this.elementRef.nativeElement;
}
ngOnInit() {
this.el.value = this.currencyPipe.transform(this.el.value);
}
@HostListener("focus", ["$event.target.value"])
onFocus(value) {
this.el.value = this.currencyPipe.parse(value); // opossite of transform
}
@HostListener("blur", ["$event.target.value"])
onBlur(value) {
this.el.value = this.cleanNumber(value); //"987654" ;//this.currencyPipe.transform(value);
}
cleanNumber (value: number) {
return 8888888; // clean logic goes here, removed for plunk example
}
}
Solution 1:[1]
You need to add Emitter for your model. This is the way to implement 2 way binding in Angular 2. Take a look at line @Output() ngModelChange = new EventEmitter(); and how I used this variable to emit the change to caller.
import { Directive, HostListener, ElementRef, OnInit, EventEmitter, Output } from "@angular/core";
import { MyCurrencyPipe } from "./my-currency.pipe";
@Directive({ selector: "[myCurrencyFormatter]" })
export class MyCurrencyFormatterDirective implements OnInit {
private el: any;
@Output() ngModelChange = new EventEmitter();
constructor(
private elementRef: ElementRef,
private currencyPipe: MyCurrencyPipe
) {
this.el = this.elementRef.nativeElement;
}
ngOnInit() {
this.el.value = this.currencyPipe.transform(this.el.value);
}
@HostListener("focus", ["$event.target.value"])
onFocus(value) {
this.el.value = this.currencyPipe.parse(value); // oposite of transform
this.ngModelChange.emit(this.el.value);
}
@HostListener("blur", ["$event.target.value"])
onBlur(value) {
this.el.value = this.cleanNumber(value); //"987654" ;//this.currencyPipe.transform(value);
this.ngModelChange.emit(this.el.value);
}
cleanNumber (value: number) {
return 8888888;
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Get Off My Lawn |
