I thought QML supported lambda functions because of JavaScript's support of anonymous functions and the fact that functions are first class objects, but they don't work how I expected. Take this code:
Item {
property var items: []
function handler( item ) {
console.log( item );
}
Component.onCompleted: {
for ( var i = 0; i < 3; ++i ) {
var item = someObj.createObject();
item.someValueChanged.connect( function() {
handler( item ); } );
items.push( item );
console.log( "Adding:", item );
}
}
Component {
id: someObj
Item {
property bool someValue: false
Timer {
running: true
onTriggered: {
parent.someValue = true;
}
}
}
}
}
I'm trying to use the lambda function() { handler( item ); }
so that when the someObj::someValueChanged
signal is emitted the emitting item is passed to the handler( item )
function.
I assumed that each loop would create a new instance of the lambda and that the item
reference would carry the reference of the someObj
instance created in that loop (i.e. item
would be captured by the lambda). But that doesn't seem to be the case as the output is:
qml: Adding: QQuickItem_QML_1(0x2442aa0)
qml: Adding: QQuickItem_QML_1(0x2443c00)
qml: Adding: QQuickItem_QML_1(0x2445370)
qml: QQuickItem_QML_1(0x2445370)
qml: QQuickItem_QML_1(0x2445370)
qml: QQuickItem_QML_1(0x2445370)
As you can see, either the whole function is being replaced on each loop or just the item
reference, so that ultimately only the last created someObj
is referred to. Can someone explain to me why lambdas (if that's even what it is) don't work the way I expect? And is this a QML issue, or a general JavaScript one?