シグナルを JavaScript メソッドに接続する適切な方法は何ですか?

シグナルを JavaScript メソッドに接続する適切な方法は何ですか?

Ubuntu の電話アプリケーションでは、イベントが発生したときに何らかのロジックを実行する必要があります。QML を JavaScript の行で汚染したくないので、外部ファイルにクラスを作成し、そのメソッドの 1 つに信号を接続しました。

メイン.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)
            }
        }
    }
}

アクション

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

「プロセス」が関数として認識されないのはなぜですか? 何か間違っているのでしょうか?

答え1

当面の問題は、 内の関数定義内でコンテキストが変わることだと私は考えていますActionthis内のオブジェクトAction.handleClick()は でありAction.handleClick、 ではありませんAction

しかし、少し戻って考えてみましょう。なぜここで関数内の関数パラダイムを使用しているのでしょうか。これは、ブラウザの JavaScript では一般的です。その環境には名前空間がないためです。他の関数を踏みにじらないようにするために、すべての関数を保持するオブジェクトを作成して、名前空間を偽装します。

しかし、QMLするAction名前空間を設定します。QML ファイルから参照する必要があることに注意してくださいActionJS.Action。したがって、関数に別の名前空間を実装する必要はありません。関数を 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 ファイルで使用する場合。

関連情報