Trigger <name>Changed events on array methods
-
Hello everyone,
I have an array in qml code defined as a property in a Component
@property var myarray: [ ]
Component.onCompleted: myarray = populateMyArray();@Then I define:
@onMyarrayChanged: console.log("myarray changed!") // just for test@Now each time I reassign the array myarray this way:
@myarray = [ /* Some contents here */]@onMyarrayChanged is called correctly, but if I call a Array.prototype method, for example:
@myarray.push("Another element") @onMyarrayChanged isn't called at all as I would like, because without the signal myarrayChanged, ListViews or Repeater that uses myarray as a model aren't updated accordingly. The only way is to reassign the model or do this:
@myarray = myarray@Is there another way I haven't thought of? Is this a bug or the expected behaviour?
Thanks for your support,
Giulio -
This is expected (although unfortunate) behaviour. The change signal will only be emitted if the value of the property itself changes, and in your case, the value of the property remains unchanged (ie, it is a reference to the array) even though the content of the array changes.
For sequence types defined in C++, the semantics are more intuitive but element-wise updates of a sequence are discouraged for performance reasons if you're updating multiple elements at the same time. More discussion about the way change signals for sequence types (and value types, which are similar) are emitted exists in the performance considerations documentation.
Cheers,
Chris. -
Thank you Chris for the help.
At the end I have found that I can call myarrayChanged() every time I finish to .push() or .pop() items from myarray. Is this the best solution to my problem? -
Sure, manually emitting the signal is a good way to ensure that appropriate signal handlers and bindings get evaluated after a change (indeed, this is what you have to do in C++ if you're handling property modifications manually).
Probably best to wrap the push/pop+signalEmission into helper functions, for convenience.
Cheers,
Chris.