下拉字段存储一个字符串作为其值,将字符串作为其文本。通过 值是与语言无关的键,用于访问文本和 在 Blockly 切换时不会翻译。文本为 向用户显示的直观易懂的字符串。
下拉字段
编辑器已打开的下拉菜单字段
收起的块上的下拉字段
恣意创作
下拉菜单构造函数采用菜单生成器和一个可选的 验证器。菜单生成器包含大量 但它本质上是一组选项,其中每个选项都包含 和与语言无关的字符串。
简单的文本下拉菜单
JSON
{
"type": "example_dropdown",
"message0": "drop down: %1",
"args0": [
{
"type": "field_dropdown",
"name": "FIELDNAME",
"options": [
[ "first item", "ITEM1" ],
[ "second item", "ITEM2" ]
]
}
]
}
JavaScript
Blockly.Blocks['example_dropdown'] = {
init: function() {
this.appendDummyInput()
.appendField('drop down:')
.appendField(new Blockly.FieldDropdown([
['first item', 'ITEM1'],
['second item', 'ITEM2']
]), 'FIELDNAME');
}
};
将人类可读的信息与中性语言键分开
允许在不同语言之间保留下拉菜单的设置。对于
例如,代码块的英文版可以定义 [['left', 'LEFT'], ['right',
'RIGHT]]
,而同一代码块的德语版本可定义 [['links',
'LEFT'], ['rechts', 'RIGHT]]
。
图片下拉菜单
下拉菜单中的选项也可以是图片(而非文字)。图片对象
使用 src
、width
、height
和 alt
属性指定。
请注意,虽然下拉菜单中可以同时包含文字选项和图片选项, 目前,单个选项无法同时包含图片和文字。
JSON
{
"type": "image_dropdown",
"message0": "flag %1",
"args0": [
{
"type": "field_dropdown",
"name": "FLAG",
"options": [
["none", "NONE"],
[{"src": "canada.png", "width": 50, "height": 25, "alt": "Canada"}, "CANADA"],
[{"src": "usa.png", "width": 50, "height": 25, "alt": "USA"}, "USA"],
[{"src": "mexico.png", "width": 50, "height": 25, "alt": "Mexico"}, "MEXICO"]
]
}
]
}
JavaScript
Blockly.Blocks['image_dropdown'] = {
init: function() {
var input = this.appendDummyInput()
.appendField('flag');
var options = [
['none', 'NONE'],
[{'src': 'canada.png', 'width': 50, 'height': 25, 'alt': 'Canada'}, 'CANADA'],
[{'src': 'usa.png', 'width': 50, 'height': 25, 'alt': 'USA'}, 'USA'],
[{'src': 'mexico.png', 'width': 50, 'height': 25, 'alt': 'Mexico'}, 'MEXICO']
];
input.appendField(new Blockly.FieldDropdown(options), 'FLAG');
}
};
动态下拉列表
JSON
{
"type": "dynamic_dropdown",
"message0": "day %1",
"args0": [
{
"type": "input_dummy",
"name": "INPUT"
}
],
"extensions": ["dynamic_menu_extension"]
}
Blockly.Extensions.register('dynamic_menu_extension',
function() {
this.getInput('INPUT')
.appendField(new Blockly.FieldDropdown(
function() {
var options = [];
var now = Date.now();
for(var i = 0; i < 7; i++) {
var dateString = String(new Date(now)).substring(0, 3);
options.push([dateString, dateString.toUpperCase()]);
now += 24 * 60 * 60 * 1000;
}
return options;
}), 'DAY');
});
这是使用 JSON 完成的 扩展程序。
JavaScript
Blockly.Blocks['dynamic_dropdown'] = {
init: function() {
var input = this.appendDummyInput()
.appendField('day')
.appendField(new Blockly.FieldDropdown(
this.generateOptions), 'DAY');
},
generateOptions: function() {
var options = [];
var now = Date.now();
for(var i = 0; i < 7; i++) {
var dateString = String(new Date(now)).substring(0, 3);
options.push([dateString, dateString.toUpperCase()]);
now += 24 * 60 * 60 * 1000;
}
return options;
}
};
也可以为下拉菜单提供函数,而不是静态列表
选项,这使得选项是动态的。该函数应返回一个
同一 [human-readable-value, language-neutral-key]
中的选项数组
静态选项。每次用户点击下拉菜单时,函数都会
并重新计算选项。
序列化
JSON
下拉菜单字段的 JSON 如下所示:
{
"fields": {
"FIELDNAME": "LANGUAGE-NEUTRAL-KEY"
}
}
其中 FIELDNAME
是引用下拉菜单字段的字符串,以及
值是应用于该字段的值。该值应为
与语言无关的选项键。
XML
下拉菜单字段的 XML 如下所示:
<field name="FIELDNAME">LANGUAGE-NEUTRAL-KEY</field>
其中字段的 name
属性包含引用下拉菜单的字符串
字段,而内部文本是要应用于该字段的值。内部
text 应为有效的中性选项键。
自定义
下拉箭头
Blockly.FieldDropdown.ARROW_CHAR
属性可用于更改
表示下拉箭头的 Unicode 字符。
ARROW_CHAR
属性在 Android 设备上默认设为 \u25BC
(▼),在 Android 设备上默认设为 \u25BE
(▾)
否则。
这是一个全局属性,因此在设置后会修改所有下拉菜单字段。
菜单高度
Blockly.FieldDropdown.MAX_MENU_HEIGHT_VH
属性可用于更改
菜单的最大高度。它以占视口的百分比表示
高度,视口即为窗口。
MAX_MENU_HEIGHT_VH
属性默认为 0.45。
这是一个全局属性,因此在设置后会修改所有下拉菜单字段。
前缀/后缀匹配
如果所有下拉菜单选项具有相同的前缀和/或后缀 这些字词会被自动分离出来并作为静态文本插入。 例如,您可以通过以下两种方式创建相同的屏蔽设置(首先是 后缀匹配,第二种则采用以下格式:
不使用后缀匹配:
JSON
{
"type": "dropdown_no_matching",
"message0": "hello %1",
"args0": [
{
"type": "field_dropdown",
"name": "MODE",
"options": [
["world", "WORLD"],
["computer", "CPU"]
]
}
]
}
JavaScript
Blockly.Blocks['dropdown_no_matching'] = {
init: function() {
var options = [
['world', 'WORLD'],
['computer', 'CPU']
];
this.appendDummyInput()
.appendField('hello')
.appendField(new Blockly.FieldDropdown(options), 'MODE');
}
};
使用后缀匹配时:
JSON
{
"type": "dropdown_with_matching",
"message0": "%1",
"args0": [
{
"type": "field_dropdown",
"name": "MODE",
"options": [
["hello world", "WORLD"],
["hello computer", "CPU"]
]
}
]
}
JavaScript
Blockly.Blocks['dropdown_with_matching'] = {
init: function() {
var options = [
['hello world', 'WORLD'],
['hello computer', 'CPU']
];
this.appendDummyInput()
.appendField(new Blockly.FieldDropdown(options), 'MODE');
}
};
这种方法的一个优点是
其他语言前面的代码包含字符串 'hello'
、'world'
和
'computer'
,而修改后的代码包含字符串 'hello world'
和
'hello computer'
。与翻译相比,译员翻译短语所用的时间要简单得多
字词。
这种方法的另一个优势是
语言。假设有一种语言使用 'world hello'
和 'computer hello'
。
后缀匹配算法将检测通用 'hello'
并将其显示
。
但是,有时前缀/后缀匹配会失败。在某些情况下
两个单词应始终结合在一起,且不应去除前缀。
例如,'drive red car'
和 'drive red truck'
可以说只能是
已排除 'drive'
,而非 'drive red'
。Unicode 不间断
可以使用空格 '\u00A0'
代替常规空格,以抑制
前缀/后缀匹配器。因此,可以使用以下代码
'drive red\u00A0car'
和'drive red\u00A0truck'
。
前缀/后缀匹配失败的另一个地方是不
用空格分隔各个字词。中文就是很好的例子。字符串
'訪問中國'
表示 'visit China'
,请注意字词之间没有空格。
最后两个字符 ('中國'
) 代表“'China'
”,
但如果进行拆分,则分别表示 'centre'
和 'country'
。为了让
前缀/后缀匹配适用于中文、
只需在需要插入空格的位置插入一个空格即可。例如 '訪問 中國'
和
'訪問 美國'
会生成 "visit [China/USA]"
,而 '訪問 中 國'
和
'訪問 美 國'
将导致 "visit [centre/beautiful] country"
。
创建下拉菜单验证器
下拉列表字段的值是与语言无关的字符串,因此任何验证工具都必须
接受字符串并返回可用选项的字符串、null
或
undefined
。
如果验证器返回任何其他内容,Blockly 的行为将处于未定义状态, 程序可能会崩溃
例如,您可以定义一个包含三个选项和 验证工具,如下所示:
validate: function(newValue) {
this.getSourceBlock().updateConnections(newValue);
return newValue;
},
init: function() {
var options = [
['has neither', 'NEITHER'],
['has statement', 'STATEMENT'],
['has value', 'VALUE'],
];
this.appendDummyInput()
// Pass the field constructor the options list, the validator, and the name.
.appendField(new Blockly.FieldDropdown(options, this.validate), 'MODE');
}
validate
始终会返回它传递的值,但它会调用帮助程序
函数 updateConnection
,用于根据下拉菜单添加或移除输入
值:
updateConnections: function(newValue) {
this.removeInput('STATEMENT', /* no error */ true);
this.removeInput('VALUE', /* no error */ true);
if (newValue == 'STATEMENT') {
this.appendStatementInput('STATEMENT');
} else if (newValue == 'VALUE') {
this.appendValueInput('VALUE');
}
}