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

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

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

Основной.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)
            }
        }
    }
}

действие.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

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

решение1

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

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

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

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

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

Затем в вашем QML-файле выполните:

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

Или просто

onClicked: ActionJS.handleClick()

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

Связанный контент