如何在Blockly自定义块的`onchange`事件中获取值?

时间:2022-09-26 20:53:55

I am making a custom block for Blockly and need to validate the inputs. In the onchange event, I want to warn the user if they are entering an invalid value for the input.

我正在为Blockly制作一个自定义块,需要验证输入。在onchange事件中,我想警告用户是否输入了无效的输入值。

Here is my block:

这是我的块:

如何在Blockly自定义块的`onchange`事件中获取值?

Blockly.Blocks['motor'] = {
    init: function() {
        this.setHelpUrl('http://www.example.com/');
        this.setColour(65);
        this.appendDummyInput()
            .appendField("motor( ");
        this.appendValueInput("port_number")
            .setCheck("Number");
        this.appendDummyInput()
            .appendField(");");
        this.setInputsInline(true);
        this.setPreviousStatement(true);
        this.setNextStatement(true);
        this.setTooltip('');
    },
    onchange: function(ev) {
        if (this.getFieldValue('port_number') > '3') {
            this.setWarningText('Port must be 0 - 3.');
        } else {
            this.setWarningText(null);
        }
    }
};

On the Blockly Developers Page, it has a basic example of getting an input value. However, I keep getting an undefined returned every time the onchange fires.

在Blockly Developers页面上,它有一个获取输入值的基本示例。但是,每次onchange触发时我都会返回一个未定义的内容。

How can I handle validation for these inputs? I don't want to create a dropdown for the input because I need to be able to input from variables, int blocks, etc.

如何处理这些输入的验证?我不想为输入创建一个下拉列表,因为我需要能够从变量,int块等输入。

2 个解决方案

#1


Not sure if this is the best way to handle this, but it is working for me. I just access the input value using the valueToCode method. Then I can validate the input value.

不确定这是否是处理此问题的最佳方法,但它对我有用。我只是使用valueToCode方法访问输入值。然后我可以验证输入值。

Note: The context of the onchange handler is the block, so passing this as the first argument to Blockly.C.valueToCode will get the value from the correct block.

注意:onchange处理程序的上下文是块,因此将此作为Blockly.C.valueToCode的第一个参数传递将从正确的块中获取值。

Blockly.Blocks['motor'] = {
    init: function() {
        this.setHelpUrl('http://www.example.com/');
        this.setColour(65);
        this.appendDummyInput()
            .appendField("motor( ");
        this.appendValueInput("port_number")
            .setCheck("Number");
        this.appendDummyInput()
            .appendField(");");
        this.setInputsInline(true);
        this.setPreviousStatement(true);
        this.setNextStatement(true);
        this.setTooltip('');
    },
    onchange: function(ev) {
        var port_number = Blockly.C.valueToCode(this, 'port_number', Blockly.C.ORDER_ATOMIC);
        var valid = VALIDATE.motor_port_number(port_number);
        if (!valid) 
            alert("WARNING: The value for the motor port must be 0, 1, 2 or 3.");
        }
    }
};

#2


Try this:

this.getInputTargetBlock('port_number').toString()

Or:

this.getInputTargetBlock('port_number').getFieldValue(/*field_name*/)

Example:

   Blockly.Blocks['stop_actions'] = {
    init: function() {
        var actions_descriptors = [
            ['HOLD', 'hold'],
            ['COAST', 'coast']
        ];
        this.appendDummyInput()
            .appendField(new Blockly.FieldDropdown(actions_descriptors), 'action')
            .setAlign(Blockly.ALIGN_RIGHT);
        this.setOutput(true, 'String');
        this.setColour(60);
        this.setTooltip('Select the stop action');
    }
};

Blockly.Blocks['motor'] = {
    init: function() {
        this.appendValueInput('arg_stop_action')
            .appendField('Stop action')
            .setAlign(Blockly.ALIGN_RIGHT);
    },

    onchange: function(e) {
        this.getInputTargetBlock('arg_stop_action').getFieldValue('action')
    }
};

#1


Not sure if this is the best way to handle this, but it is working for me. I just access the input value using the valueToCode method. Then I can validate the input value.

不确定这是否是处理此问题的最佳方法,但它对我有用。我只是使用valueToCode方法访问输入值。然后我可以验证输入值。

Note: The context of the onchange handler is the block, so passing this as the first argument to Blockly.C.valueToCode will get the value from the correct block.

注意:onchange处理程序的上下文是块,因此将此作为Blockly.C.valueToCode的第一个参数传递将从正确的块中获取值。

Blockly.Blocks['motor'] = {
    init: function() {
        this.setHelpUrl('http://www.example.com/');
        this.setColour(65);
        this.appendDummyInput()
            .appendField("motor( ");
        this.appendValueInput("port_number")
            .setCheck("Number");
        this.appendDummyInput()
            .appendField(");");
        this.setInputsInline(true);
        this.setPreviousStatement(true);
        this.setNextStatement(true);
        this.setTooltip('');
    },
    onchange: function(ev) {
        var port_number = Blockly.C.valueToCode(this, 'port_number', Blockly.C.ORDER_ATOMIC);
        var valid = VALIDATE.motor_port_number(port_number);
        if (!valid) 
            alert("WARNING: The value for the motor port must be 0, 1, 2 or 3.");
        }
    }
};

#2


Try this:

this.getInputTargetBlock('port_number').toString()

Or:

this.getInputTargetBlock('port_number').getFieldValue(/*field_name*/)

Example:

   Blockly.Blocks['stop_actions'] = {
    init: function() {
        var actions_descriptors = [
            ['HOLD', 'hold'],
            ['COAST', 'coast']
        ];
        this.appendDummyInput()
            .appendField(new Blockly.FieldDropdown(actions_descriptors), 'action')
            .setAlign(Blockly.ALIGN_RIGHT);
        this.setOutput(true, 'String');
        this.setColour(60);
        this.setTooltip('Select the stop action');
    }
};

Blockly.Blocks['motor'] = {
    init: function() {
        this.appendValueInput('arg_stop_action')
            .appendField('Stop action')
            .setAlign(Blockly.ALIGN_RIGHT);
    },

    onchange: function(e) {
        this.getInputTargetBlock('arg_stop_action').getFieldValue('action')
    }
};