I've found this somewhat later, but I thought I'd respond.
There is a undocumented parameter expression that returns the name of the data object name (not the input name or id):
console.log("changed: " + event.getParam("expression") + " " + event.getParam("oldValue") + " -> " + event.getParam("value"));
Results in:
changed: v.leadInfo.lastName Last N -> Last Na
The change handler can be used to show or hide elements when a value changes from blank to a value (or the other way around) using $A.util.removeClass/addClass, or to run a form validation method.
Here's an example of my helper that does these things (it's an input form for a wrapperClass):
({
init : function(component) {
},
onLeadInfoChange: function(component, event) {
// INITIAL LOAD
if (!component.get("v.leadInfoOrg")) {
var lead = component.get("v.leadInfo");
// store initial object for possible reset
var leadOrg = Object.assign({}, lead); // clone
component.set("v.leadInfoOrg", leadOrg);
}
this.validateForm(component);
// set initial hidden/visible fields
if (event.getParam("expression").endsWith("leadInfo")) {
this.toggleField(component, "account", component.get("v.leadInfo.accountName"));
this.toggleField(component, "contact", component.get("v.leadInfo.lastName"));
}
if (event.getParam("expression").endsWith("accountName")) {
this.toggleFieldwithOld(component, "account", event.getParam("value"), event.getParam("oldValue"));
}
if (event.getParam("expression").endsWith("lastName")) {
this.toggleFieldwithOld(component, "contact", event.getParam("value"), event.getParam("oldValue"));
}
//console.log("MF_LeadForm.onLeadInfoChange: " + event.getParam("expression") + " " + event.getParam("oldValue") + " -> " + event.getParam("value"));
},
showForm: function(component, show) {
component.set("v.showForm", show);
},
resetForm: function(component) {
component.set("v.leadInfo", component.get("v.leadInfoOrg"));
},
submitForm: function(component, event, handler){
event.preventDefault();
// form is valid; updating Org and hide form
var leadOrg = Object.assign({}, component.get("v.leadInfo")); // clone
component.set("v.leadInfoOrg", leadOrg);
this.showForm(component, false);
},
validateForm: function(component) {
var fields=["accountName", "billingStreet", "billingPostalCode", "billingCity", "salutation", "firstName", "lastName", "contactPhone", "accountPhone", "email"];
var field = "";
var validity = null;
for (var i=0; i<fields.length; i++) {
field=component.find(fields[i]);
validity=field.get('v.validity');
if (typeof validity == 'object' && validity != null) {
if (!validity.valid){
component.set("v.validity", false);
console.log(fields[i]+': invalid.');
return;
}
}
}
component.set("v.validity", true);
},
toggleField: function(component, name, value) {
if (value) {
this.showField(component, name);
} else if (!value) {
this.hideField(component, name);
}
},
toggleFieldwithOld: function(component, name, value, oldValue) {
if (value && !oldValue) {
this.showField(component, name);
} else if (!value && oldValue) {
this.hideField(component, name);
}
},
hideField: function(component, name) {
$A.util.addClass(component.find(name), "slds-hide");
$A.util.removeClass(component.find("no-" + name), "slds-hide");
},
showField: function(component, name) {
$A.util.removeClass(component.find(name), "slds-hide");
$A.util.addClass(component.find("no-" + name), "slds-hide");
}
})