Unsolved Object.defineProperty outside a JS scope
-
Hi,
I'm trying to add dynamically properties to Rectangle objects.
My code works fine except one point: I'm not able to access to my new created properties outside a Javascrip scope.
Here is my code:
Window { visible: true width: 1300 height: 800 title: qsTr("Tests") id: component Column { spacing: 3 Label { text: rectA.myValue ? rectA.myValue : "value not found" } // display "value not found" Label { text: rectB.myValue ? rectB.myValue : "value not found" } // display "value not found" Button { text: "check a" onClicked: console.log(rectA.myValue) // display "This is a test" } } Rectangle { id: rectA } Rectangle { id: rectB } property var objects: [rectA, rectB] Component.onCompleted: { objects.forEach( (o) => { let obj = Object.defineProperty(o, "myValue", { enumerable: true, configurable: true, writable: true, value: "This is a test" }) console.log(o.myValue) // display "This is a test" }) } }
Did I make a mistake or it's impossible to dynamically add a property to an object and read it outside a JS scope ?
Thanks a lot ! ^^
-
This is because it is not an QML property. This means when it is set - nothing changed for your binding at label text. Sad story, but since it is not an QML property, you cannot call
o.myValueChanged();
.
But you can do another trick. Add another dummy property to yor rectangles:Rectangle { id: rectA; property string dummy: "" }
Then add this property to label text:
Label { text: (rectA.myValue ? rectA.myValue : "value not found") + rectA.dummy }
Notify about value changed:
let obj = Object.defineProperty(o, "myValue", { enumerable: true, configurable: true, writable: true, value: "This is a test" }) o.dummyChanged();
Not sure if it is a good idea. but it works. Personally, I prefer to add one
var
property to a Rectangle and extend it as simple JS object. But in this case you should also notify that this property changed:Column { spacing: 3 Label { text: rectA.props.myValue || "value not found" } Label { text: rectB.props.myValue || "value not found" } } Rectangle { id: rectA; property var props: ({}) } Rectangle { id: rectB; property var props: ({}) } property var objects: [rectA, rectB] Component.onCompleted: { objects.forEach( (o) => { o.props["myValue"] = "This is a test"; o.propsChanged(); }) }
-
Oh, well, it's make sens. Thank you for your answer and your solution. =D