首页 > 解决方案 > Javascript访问父变量的正确方法

问题描述

Qt 在https://doc.qt.io/qt-5/qtquick-performance.html中指定以下代码。accumulatedValue 变量作为“root.accumulatedValue”访问,只是“accumulatedValue”。只是想了解在这种情况下访问父变量的正确方法是什么。

// good.qml
import QtQuick 2.3

Item {
    id: root
    width: 200
    height: 200
    property int accumulatedValue: 0

    Text {
        anchors.fill: parent
        text: root.accumulatedValue.toString()
        onTextChanged: console.log("text binding re-evaluated")
    }

    Component.onCompleted: {
        var someData = [ 1, 2, 3, 4, 5, 20 ];
        var temp = accumulatedValue;
        for (var i = 0; i < someData.length; ++i) {
            temp = temp + someData[i];
        }
        accumulatedValue = temp;
    }
}

标签: javascriptqtqml

解决方案


当从与其所属对象相同的范围id内访问属性时,不需要使用 an 来限定该访问。当从不同的范围访问该属性时,您应该使用id该属性所属的对象来限定它。

使用qmllint举一些例子:

import QtQuick 2.3

Item {
    id: root
    width: 200
    height: 200
    property int accumulatedValue: 0

    Text {
        /*
            Warning: unqualified access at /tmp/good.qml:20:21

                    objectName: accumulatedValue
                                ^^^^^^^^^^^^^^^^
            Note: accumulatedValue is a member of the root element
                  You can qualify the access with its id to avoid this warning:

                    objectName: root.accumulatedValue
        */
        objectName: accumulatedValue
        anchors.fill: parent
        // Fine; qualified with id.
        text: root.accumulatedValue

        Component.onCompleted: {
            /*
                Warning: unqualified access at /tmp/good.qml:36:19

                            print(accumulatedValue)
                                  ^^^^^^^^^^^^^^^^
                Note: accumulatedValue is a member of the root element
                      You can qualify the access with its id to avoid this warning:

                            print(root.accumulatedValue)
            */
            print(accumulatedValue)
        }
    }

    Component.onCompleted: {
        var someData = [ 1, 2, 3, 4, 5, 20 ];
        // Fine; in same scope.
        var temp = accumulatedValue;
        for (var i = 0; i < someData.length; ++i) {
            temp = temp + someData[i];
        }
        accumulatedValue = temp;
    }
}

不合格的访问成本很高,因为它们需要引擎搜索各种范围才能找到属性。

另一个原因是可读性,在上面链接的范围文档中进行了解释:

动态范围非常强大,但必须谨慎使用以防止 QML 代码的行为变得难以预测。一般来说,它应该只在两个组件已经以另一种方式紧密耦合的情况下使用。在构建可重用组件时,最好使用属性接口 [...]


推荐阅读