Qual é a maneira correta de conectar um sinal a um método JavaScript?

0

Em um aplicativo de telefone do Ubuntu, preciso executar alguma lógica quando um evento ocorre. Como não quero poluir o QML com muitas linhas de JavaScript, criei uma classe em um arquivo externo e conectei o sinal a um de seus métodos:

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...')
    }
}

Funciona, mas não consigo chamar nenhum outro método do slot:

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

Por que o 'processo' não é reconhecido como uma função? Estou fazendo algo errado?

    
por Cos64 28.05.2015 / 16:09

1 resposta

2

Eu acredito que o problema imediato é que o contexto muda dentro das definições de função dentro de Action . O objeto this dentro de Action.handleClick() é Action.handleClick , não Action .

Mas vamos voltar um pouco: por que você está usando o paradigma de função dentro de uma função aqui? Isso é comum no Javascript do navegador, já que não há namespace nesse ambiente. Para evitar atropelar outras funções, você falsifica um namespace criando um objeto para manter todas as suas funções.

No entanto, o QML faz o namespace. Observe que você precisou referenciar Action as ActionJS.Action do arquivo QML. Portanto, não há necessidade de implementar outro namespace para suas funções; basta colocá-los no nível superior do arquivo JS:

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

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

Em seguida, no seu arquivo QML, faça

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

Ou apenas

onClicked: ActionJS.handleClick()

Estou assumindo aqui que você realmente não precisa de um objeto Action para nada além de namespacing. Se fizer isso, você deve conhecer o protótipo . Você também pode querer saber sobre .pragma library , se você pretende usar este arquivo JS em vários arquivos QML.

    
por Robert Schroll 28.05.2015 / 17:24