Как правильно подключить сигнал к методу JavaScript?

В приложении для телефона Ubuntu мне нужно выполнить некоторую логику, когда происходит событие. Поскольку я не хочу загрязнять QML слишком большим количеством строк JavaScript, я создал класс во внешнем файле и подключил сигнал к одному из его методов:

Main.qml

import QtQuick 2.0
import Ubuntu.Components 1.1
import "action.js" as ActionJs

MainView {
    objectName: "mainView"

    applicationName: "example.cos64"

    useDeprecatedToolbar: false

    width: units.gu(20)
    height: units.gu(20)

    Page {

        Button {
            id: clickMeButton

            text: "Click me"

            onClicked: {
                console.log('clicked');
            }

            Component.onCompleted: {
                var action = new ActionJs.Action();
                clickMeButton.clicked.connect(action.handleClick)
            }
        }
    }
}

action.js

function Action() {

    this.handleClick = function() {
        console.log('handleClick');
        this.process();
    }

    this.process = function() {
        console.log('processing...')
    }
}

Это работает, но я не могу вызвать другой метод из слота:

Starting /usr/lib/x86_64-linux-gnu/qt5/bin/qmlscene...
qml: clicked
qml: handleClick
file:///home/co64/projects/ubuntu/Example/action.js:5: TypeError: Property 'process' of object [object Object] is not a function

Почему «процесс» не распознается как функция? Я что-то не так делаю?

0
задан 28 May 2015 в 17:09

1 ответ

Я считаю, что непосредственная проблема заключается в том, что контекст изменяется внутри определений функций внутри Action. Объект this внутри Action.handleClick() - это Action.handleClick, а не Action.

Но давайте вернемся немного назад: почему вы используете здесь парадигму «функция внутри функции»? Это часто встречается в браузере Javascript, поскольку в этой среде нет пространства имен. Чтобы не растоптать другие функции, вы подделываете пространство имен, создавая объект, содержащий все ваши функции.

Однако, QML делает пространство имен. Обратите внимание, что вам пришлось ссылаться на Action как ActionJS.Action из файла QML. Следовательно, нет необходимости реализовывать другое пространство имен для ваших функций; просто поместите их в верхний уровень файла JS:

function handleClick() {
    console.log("handleClick");
    process();
}

function process() {
    console.log("processing...");
}

Затем в своем файле QML выполните

Component.onCompleted: {
    clickMeButton.clicked.connect(ActionJS.handleClick)
}

Или просто

onClicked: ActionJS.handleClick()

I Здесь я предполагаю, что вам на самом деле не нужен объект Action для чего-либо, кроме пространства имен. Если вы это сделаете, вы должны узнать о прототипе . Вы также можете узнать о .pragma library , если собираетесь использовать этот файл JS в нескольких файлах QML.

0
ответ дан 28 May 2015 в 17:09

Другие вопросы по тегам:

Похожие вопросы: