更新 QML 中 var 属性的绑定

Update bindings to var properties in QML

如果您看一下 this page,它会注意到当对象更改时,对 var 属性的绑定不会自动更新:

Item {
    property var car: new Object({wheels: 4})

    Text {
        text: "The car has " + car.wheels + " wheels";
    }

    Component.onCompleted: {
        car.wheels = 6;
    }
}

那会说 "The car has 4 wheels" 因为 car.wheels = 6; 不会自动触发更新。

页面没有说明如何解决这个问题?如何手动触发更新(不替换整个 car 对象)。

编辑: 明确地说,我不想替换整个 car 对象,我 do想使用 property var(我的实际 属性 是一个 javascript 对象,不能存储在任何原生 QML 属性 类型中)。

编辑 2: 下面是一个使用 QtObject 的例子 工作(它说 "The car has 0 wheels.":

import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2

ApplicationWindow {
    width: 640
    height: 480
    visible: true

    property var car: QtObject { property var wheels: [] }

    Item {

        Text {
            text: "The car has " + car.wheels.length + " wheels";
        }

        Component.onCompleted: {
            car.wheels.push("Rear-left");
            car.wheels.push("Rear-right");
            car.wheels.push("Front-left");
            car.wheels.push("Front-right");
        }
    }
}

实际上,页面 确实 说明了如何解决此问题:

If the onCompleted handler instead had "car = new Object({wheels: 6})" then the text would be updated to say "The car has 6 wheels", since the car property itself would be changed, which causes a change notification to be emitted.

尽管我认为这违背了您不替换整个 car 对象的要求。

也就是说,还有(至少)另一种选择——使用 QtObject:

Item
{
    property var car: QtObject { property int wheels: 4 }

    Text {
        text: "The car has " + car.wheels + " wheels";
    }

    Component.onCompleted: {
        car.wheels = 6;  // This will update the text
    }
}

编辑

鉴于新示例,如果您需要使用包含基本类型的 Javascript 数组,您列出的代码将不会触发更新。但是,如果您能够使用包含 QML 类型的 list,则可以使用以下解决方法:

import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2

ApplicationWindow {
    id: window
    width: 640
    height: 480
    visible: true

    property var car: QtObject { property list<Item> wheels }

    Component
    {
        id: wheelComponent
        QtObject
        {
            property var wheelName;
        }
    }

    Text
    {
        anchors.fill: parent
        text: "The car has " + car.wheels.length + " wheels";

        Component.onCompleted:
        {
            var wheel = wheelComponent.createObject(window, {"wheelName": "Rear-left"} );
            car.wheels += wheel;
        }
    }
}

这对您的需求来说可能有些苛刻。创建 property bool update 并在您更改数组时更改它的 hack 方法可能更可取。

我用这种方式解决了同样的问题:

Item {
    property var car: new Object({wheels: 4})

    Text {
        Connections {
            target: car
            onWheelsChanged: {
                text: "The car has " + car.wheels + " wheels";
            }   
        }

        text: "The car has " + car.wheels + " wheels";
    }

    Component.onCompleted: {
        car.wheels = 6;
    }
}

通知和自动绑定重新评估仅支持 QML 属性,不支持 JS 对象成员。

对于var中的JS对象,只有当实际对象与另一个对象发生变化时才会触发通知,但当对象内部发生变化时不会触发通知。

然而,您可以通过在内部对象更改后手动发出 carChanged() 来强制重新评估绑定。