Как заставить JS eval() работать в родительской области элемента QML

Если у меня есть некоторый код JS в виде текста, и я вызываю его в eval(), я могу использовать функции, определенные этим оператором, только в области, в которой произошло eval(). Насколько я могу судить, это означает, что любые новые определения JS, созданные из eval, невидимы для остальной части QML. Рассмотрим этот обработчик сигналов QML:

Item {
    id: testitem
    onThesourceChanged: {
        eval(thesource)
        testfunction()
    }
}

testfunction() был определен в тексте «источник» и действительно работает в обработчике сигнала выше, выводя некоторый тестовый текст; но он не входит в область действия элемента QML и, насколько я понимаю, не может быть вызван снова. Я пробовал различные идеи, такие как размещение eval() в функции или внутри Component.onCompleted и т. д., но я не могу понять, как заставить что-либо, созданное eval(), распознаваться как часть родительского элемента QML.

Например, я хочу иметь возможность вызывать testitem.testfunction(), но он не определен вне области действия этого обработчика.


person John Vitornio    schedule 05.05.2014    source источник
comment
откуда вы берете eval текст?   -  person MadeOfAir    schedule 05.05.2014
comment
@MadeOfAir Я создаю его вне Qt, и до запуска этой оценки он находится в файле JS. В любом случае, это не проблема, поскольку текст анализируется и оценивается. Я просто хочу, чтобы он каким-то образом оценивался в рамках элемента QML. Но я не могу использовать QML import, потому что он загружает JS только один раз, и я хочу перезагрузить файл JS во время работы приложения, поэтому мне нужен eval   -  person John Vitornio    schedule 05.05.2014
comment
тогда почему бы не присвоить его текстовому свойству testitem и не пересчитывать при необходимости?   -  person MadeOfAir    schedule 05.05.2014
comment
@MadeOfAir да, но как его переоценить? eval должен быть где-то, и если он находится в функции, то оценка ограничена областью действия этой функции.   -  person John Vitornio    schedule 05.05.2014


Ответы (1)


Вам нужно объявить переменную в области, где вы хотите получить к ней доступ позже. Используйте eval() для инициализации в дочерней области:

import QtQuick 2.1

Rectangle {
    width: 360
    height: 360

    MouseArea {
        anchors.fill: parent
        onClicked: {
            testitem.thesource = "myfunction = function(text) { return text.toLowerCase() }"
        }
    }

    Text {
        id: testitem
        property var myfunction: function(text) { return text.toUpperCase() }
        property var thesource;
        anchors.centerIn: parent
        text: myfunction("Kullo – Secure Messaging")

        onThesourceChanged: {
            eval(thesource);
            text = myfunction("Kullo – Secure Messaging")
        }
    }
}
person Simon Warta    schedule 08.05.2014