【问题标题】:Blockly: Update other inputDummy dropdown fields based on selection of a inputDummy dropdown fieldBlockly:根据 inputDummy 下拉字段的选择更新其他 inputDummy 下拉字段
【发布时间】:2021-04-22 03:39:07
【问题描述】:

我一直在尝试在 Blockly 工作区中创建一个自定义块,该块根据对同一块中先前下拉字段的选择来更改下拉字段中的选项。 关于区块:-

  1. 共有三个下拉字段
  2. 所有内容均使用 Blockly.Extensions 动态填充
  3. 所有代码都在下面

我已经为块初始化实现了一个“onchange”函数,该函数通过“event”变量获取更改数据并做出相应的响应。我在尝试更新不断变化的下拉字段时遇到问题。请帮忙。

代码

// the block JSON declaration variable
var updateTableData = {
    "type": "al_update_table_data",
    "message0": "Update in table %1 where column %2 is %3 set value for column %4 to %5",
    "args0": [
        {
            "type": "input_dummy",
            "name": "table_input",
        },
        {
            "type": "input_dummy",
            "name": "column_input",
        },
        {
            "type": "input_value",
            "name": "get_value"
        },
        {
            "type": "input_dummy",
            "name": "column_input1",
        },
        {
            "type": "input_value",
            "name": "set_value"
        }
    ],
    "inputsInline": false,
    "previousStatement": null,
    "nextStatement": null,
    "fieldRow": false,
    "colour": 90,
    "tooltip": "Update value in a table",
    "helpUrl": "",
    "extensions": ["get_tables", "get_column", "get_column1"],
}
// the blockly extensions
// get list of tables and populate the 'table_input' drop-down field
Blockly.Extensions.register('get_tables', function () {
    this.getInput("table_input")
        .appendField(new Blockly.FieldDropdown(
            function () {
                let options = []
                let tables = JSON.parse(localStorage.getItem('applab_myTables'))
                tables.map(t => options.push([t.name, t.id]))
                return options
            }
        ), "table_input")
})

// get list of columns from the first table and populate the 'column_input' drop-down field
Blockly.Extensions.register('get_column', function () {
    this.getInput('column_input')
        .appendField(new Blockly.FieldDropdown(
            function () {
                let options = []
                let table = JSON.parse(localStorage.getItem('applab_myTables'))[0]
                Object.keys(table['columnData']).filter(cId => table['columnOrder'].includes(cId)).map(cId => options.push([table['columnData'][cId]['name'], cId]))
                return options
            }
        ), 'column_input')
})

// get list of columns from the first table, remove the column value already selected in 'column_input' and populate the 'column_input1' drop-down field
Blockly.Extensions.register('get_column1', function () {
    var selectedColumn = this.getFieldValue('column_input')
    this.getInput('column_input1')
        .appendField(new Blockly.FieldDropdown(
            function () {
                let options = []
                let table = JSON.parse(localStorage.getItem('applab_myTables'))[0]
                Object.keys(table['columnData']).filter(cId => table['columnOrder'].includes(cId)).filter(cId => cId !== selectedColumn).map(cId => options.push([table['columnData'][cId]['name'], cId]))
                return options
            }
        ), 'column_input1')
})
// Comments with 7 slashes (///////) are my commentary on the issues, errors and outputs that I get
// blockly block initialization
Blockly.Blocks['al_update_table_data'] = {
    init: function () {
        this.jsonInit(updateTableData)
    },
    onchange: function (event) {
        // console.log(event.type)
        var table_id = this.getFieldValue('table_input')
        var selectedcolumn = this.getFieldValue('column_input')
        var otherColumn = this.getFieldValue('column_input1')
        if (event.blockId === this.id) {
            if (event.type === Blockly.Events.BLOCK_CHANGE) {
                // console.log('name of changed field', event.name)
                // console.log('old value', event.oldValue)
                // console.log('new value', event.newValue)
                if (event.name === 'table_input') { 
                    // change in selected table, update column_input and column_input1
                } else if (event.name === 'column_input') {
                    // change in selected column, update column_input1
                    /////// I tried to removeField which did remove the field, but also the label on the same field row. But when I tried to getInput, I get the error: 'column_input1' input doesn't exist
                    // this.removeField('column_input1', true)
                    /////// I tried to removeInput as well, which too removed the field, but also the label on the same field row. And when I tried to getInput, I again get the error: 'column_input1' input doesn't exist
                    // this.removeInput('column_input1')
                    /////// This functions runs fine when I don't remove any input or field. But it keeps adding new drop-downs next to existing ones with new options
                    this.getInput('column_input1')
                        /////// I tried this to use removeField after getInput as well. But it shows the error: this.getInput().removeField() is not a function
                        // .removeField('column_input1')
                        .appendField(new Blockly.FieldDropdown(
                            function () {
                                let options = []
                                let table = JSON.parse(localStorage.getItem('applab_myTables')).find(table => table.id === table_id)
                                Object.keys(table['columnData']).filter(cId => table['columnOrder'].includes(cId)).filter(cId => cId !== event.newValue).map(cId => options.push([table['columnData'][cId]['name'], cId]))
                                return options
                            }
                        ), 'column_input1')
                }
            }
        }
        if (event.type === Blockly.Events.FINISHED_LOADING) {
            // workspace finished loading, update column_input and column_input1 based on selected table
        }
    }
}

这是生成的块的快照:

tldr; 当另一个下拉列表的选定选项更改时,更新块中下拉字段的选项。

谢谢, 乌特卡什

【问题讨论】:

    标签: javascript web blockly


    【解决方案1】:

    感谢来自 Google Blockly 组的@beka https://groups.google.com/g/blockly

    这里的主要问题是概念性的。一个块有

    1. 输入:字段行可以包含任何内容,例如值块(拼图输入)或语句块(乐高输入)
    2. 字段:类似于 HTML。这些可以是文本框、下拉列表、图像等。

    输入和字段都可以有名称。以不同的方式命名它们是一种很好的做法。

    从我的扩展中可以看出,我输入了this.getInput('columnInput') 并附加了一个具有相同名称的字段.appendField。因此,输入具有相同名称的字段。

    以下是更正:

    1. 到扩展:
    Blockly.Extensions.register('get_column', function () { this.getInput('column_input') .appendField(新 Blockly.FieldDropdown( 功能 () { 让选项 = [] 让表 = JSON.parse(localStorage.getItem('applab_myTables'))[0] Object.keys(table['columnData']).filter(cId => table['columnOrder'].includes(cId)).map(cId => options.push([table['columnData'][cId][ '名称'], cId])) 退货选项 } ), 'column_input_field') // 更新了与输入名称不同的字段名称 })
    1. 更新块初始化 onchange 内所有下拉列表的函数
    this.getInput('column_input').removeField('column_input_field') // 先移除字段 // 然后,使用新选项附加一个新字段 this.getInput('column_input') .appendField(新 Blockly.FieldDropdown( 功能 () { 让选项 = [] 让表 = JSON.parse(localStorage.getItem('applab_myTables')).find(table => table.id === event.newValue) Object.keys(table['columnData']).filter(cId => table['columnOrder'].includes(cId)).map(cId => options.push([table['columnData'][cId][ '名称'], cId])) 退货选项 } ), 'column_input_field') // 更新了与输入名称不同的字段名称

    当然,如果您在this.getInput('').removeField('') 期间遇到任何问题,请记录输入对象console.log(this.getInput('')) 并进行评估。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-02-21
      • 1970-01-01
      • 1970-01-01
      • 2020-02-09
      • 1970-01-01
      • 2023-03-21
      • 2011-11-22
      相关资源
      最近更新 更多