I'm using Typescript with Angular2, just like in the Angular2 Tour of Heroes tutorial.
I have an input field that I want to attach a change
event to, so that some custom logic can perform when the field is changed. I need to know the field's current value to perform the logic, so I don't want to bind that field with ngModel
, as that will override the property before I'm able to retrieve its former value before it was changed.
So I have something like:
<input (change)="handleChange(myObj, $event)" value={{ myObj.myField }}... />
Then in handleChange:
handleChange (obj: MyObjectClass, e: Event) {
oldValue: number = obj.myField;
newValue : number = parseInt(e.target.value);
// Do some logic
obj.myField = newValue;
}
While this works fine in code, the Typescript piler is throwing an error error TS2339: Property 'value' does not exist on type 'EventTarget'.
on the line newValue : number = parseInt(e.target.value);
Is there a better way of doing this?
I'm using Typescript with Angular2, just like in the Angular2 Tour of Heroes tutorial.
I have an input field that I want to attach a change
event to, so that some custom logic can perform when the field is changed. I need to know the field's current value to perform the logic, so I don't want to bind that field with ngModel
, as that will override the property before I'm able to retrieve its former value before it was changed.
So I have something like:
<input (change)="handleChange(myObj, $event)" value={{ myObj.myField }}... />
Then in handleChange:
handleChange (obj: MyObjectClass, e: Event) {
oldValue: number = obj.myField;
newValue : number = parseInt(e.target.value);
// Do some logic
obj.myField = newValue;
}
While this works fine in code, the Typescript piler is throwing an error error TS2339: Property 'value' does not exist on type 'EventTarget'.
on the line newValue : number = parseInt(e.target.value);
Is there a better way of doing this?
Share Improve this question asked Aug 19, 2016 at 20:11 A. DuffA. Duff 4,3097 gold badges43 silver badges71 bronze badges4 Answers
Reset to default 5To do validation on input values, you are better off writing a custom validator instead of trying to use change event. That being said, you can pass the input value by using a reference to the input like this:
<input #myInput (change)="handleChange(myInput.value, $event)" value={{ myObj.myField }}... />
If you see the definition of EventTarget
, it is like below,
interface EventTarget {
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
dispatchEvent(evt: Event): boolean;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}
it does not contain the value
property. so if you want to do it in right way you can use ,
e.target['value']
Now the reason why there is no value proerty on EventTarget can to support different type of events , for e.g you may use same Event for input type checked
and in that case you would like to see checked
property.
The Angular2 events don't have direct access to the event's target. You really shouldn't be accessing your value via the raw element, you should always be using a binding.
whatever.ponent.ts
export class WhateverComponent {
private tempField: any;
private handleChange(obj: MyObjectClass, e: Event) {
obj.field = this.tempField;
}
}
whatever.ponent.html
<input (change)="handleChange(myObj, $event)" [value]="tempField" />
If you really must access the element, there is the ElementRef class. However, this is a major security risk and you should heed the warning in the documentation:
Permitting direct access to the DOM can make your application more vulnerable to XSS attacks. Carefully review any use of ElementRef in your code. For more detail, see the Security Guide.
The easiest way is to use the official Get user input from a template reference variable. so it only happens in your Template
scope without affecting the Component
at all.
Something like:
<input (change)="handleChange(myObj, newValue.value)" #newValue />
// Method keep the same
handleChange (obj: MyObjectClass, e: Event) {
oldValue: number = obj.myField;
newValue : number = parseInt(e.target.value);
// Do some logic
obj.myField = newValue;
}
A bonus is if you need to bind Enter
key to the input
field, you do not have to write the annoying if($event.keyCode == 13) ...
, instead use the Key event filtering
feather and do:
(keyup.enter)="onEnter(newvalue.value)"