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
当面の問題は、 内の関数定義内でコンテキストが変わることだと私は考えていますAction
。this
内のオブジェクト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 ファイルで使用する場合。