2019 年 7 月(版本 2.20190722)添加了更加规范化的字段 API。旨在尽可能实现向后兼容。这意味着,如果您在 2019 年 7 月之前创建了自定义字段,该字段很可能会继续正常运行。在决定是否需要升级自定义字段之前,您应仔细阅读危险区域部分,并对字段进行全面测试。
由于 2019 年 7 月之前字段之间缺乏标准化,因此很难涵盖开发者可能需要进行的所有更改。本文档尝试涵盖所有可能的变化,但如果本文档未涵盖您感兴趣的内容,请阅读有关获取升级帮助的部分。
危险区域
危险区域是指 API 已更改且您的字段可能损坏的已知位置。
Blockly.Field.register
现在,您无法再通过 Blockly.Field.register();
注册字段。现在有一个 fieldRegistry
命名空间来处理注册。
Blockly.Field.register('my_field_name', myFieldClass);
会变为:
Blockly.fieldRegistry.register('my_field_name', myFieldClass);
setText
Blockly 核心不再调用 setText
函数,因此如果您的 setText
函数包含逻辑,则需要将其移至值处理函数套件、getText
函数和渲染函数(具体取决于 setText
函数的实际用途)。
CustomFields.UpgradeField.prototype.setText = function(newText) {
// Do validation.
if (typeof newText != 'string' || newText === this.text_) {
return;
}
// Fire event.
if (this.sourceBlock_ && Blockly.Events.isEnabled()) {
Blockly.events.fire(new Blockly.Events.BlockChange(
this.sourceBlock_, 'field', this.name, this.text_, newText
));
}
// Update text value.
this.text_ = 'prefix' + newText;
// Rerender.
this.size_.width = 0;
};
会变为:
CustomFields.UpgradeField.prototype.doClassValidation_ = function(newValue) {
if (typeof newValue != 'string') {
return null;
}
return newValue;
};
CustomFields.UpgradeField.prototype.getText = function() {
return 'prefix' + this.value_;
}
Blockly 会自动处理以下事项:
- 检查新值是否与旧值不同。
- 更新值。
- 触发更改事件。
- 重新渲染字段。
您需要处理以下情况:
推荐的升级
推荐升级是指字段 API 已更改,但如果您选择不进行更改,您的字段很可能仍会正常运行。
SERIALIZABLE
如需详细了解 EDITABLE
和 SERIALIZABLE
属性,请参阅可编辑和可序列化的属性。
CustomFields.UpgradeField.prototype.SERIALIZABLE = true;
您可以忽略以下警告,但也可以通过定义 SERIALIZABLE
属性来解决此问题:
Detected an editable field that was not serializable. Please define
SERIALIZABLE property as true on all editable custom fields. Proceeding
with serialization.
上述警告意味着,Blockly 认为您希望序列化该字段(因为 EDITABLE
属性为 true),但在您定义 SERIALIZABLE
属性之前无法确定。如果您选择不处理此问题,一切都会正常运行,并且您的字段会被序列化,但您会收到控制台警告。
size_.width
this.size_.width = 0;
会变为:
this.isDirty_ = true;
您可以忽略以下警告,但也可以通过设置 isDirty_
属性(而非 size_.width
属性)来解决此问题:
Deprecated use of setting size_.width to 0 to rerender a field. Set
field.isDirty_ to true instead.
上述警告表示 Blockly 检测到您正在使用旧方法重新渲染字段,并希望您使用新方法。
如需详细了解 isDirty_
属性,请参阅 isDirty_。
init
init
函数已转换为模板函数,以减少子类中的重复代码。
CustomFields.UpgradeField.prototype.init = function() {
if (this.fieldGroup_) {
// Already initialized once.
return;
}
// Call superclass.
CustomFields.UpgradeField.superClass_.init.call(this);
// Create DOM elements.
this.extraDom_ = Blockly.utils.dom.createSvgElement('image',
{
'height': '10px',
'width': '10px'
});
this.extraDom_.setAttributeNS('http://www.w3.org/1999/xlink',
'xlink:href', 'image.svg');
this.extraDom_.style.cursor = 'pointer';
this.fieldGroup_.appendChild(this.extraDom_);
// Bind events.
this.mouseOverWrapper_ =
Blockly.browserEvents.bind(
this.getClickTarget_(), 'mouseover', this, this.onMouseOver_);
this.mouseOutWrapper_ =
Blockly.browserEvents.bind(
this.getClickTarget_(), 'mouseout', this, this.onMouseOut_);
// Render.
this.setValue(this.getValue());
};
会变为:
CustomFields.UpgradeField.prototype.initView = function() {
CustomFields.UpgradeField.superClass_.initView.call(this);
this.extraDom_ = Blockly.utils.dom.createSvgElement('image',
{
'height': '10px',
'width': '10px'
});
this.extraDom_.setAttributeNS('http://www.w3.org/1999/xlink',
'xlink:href', 'image.svg');
this.extraDom_.style.cursor = 'pointer';
this.fieldGroup_.appendChild(this.extraDom_);
};
CustomFields.UpgradeField.prototype.bindEvents_ = function() {
CustomFields.UpgradeField.superClass_.bindEvents_.call(this);
this.mouseOverWrapper_ =
Blockly.bindEvent_(
this.getClickTarget_(), 'mouseover', this, this.onMouseOver_);
this.mouseOutWrapper_ =
Blockly.bindEvent_(
this.getClickTarget_(), 'mouseout', this, this.onMouseOut_);
};
这意味着,Blockly 现在可以自动处理以下情况:
- 检查字段是否已初始化。
- 创建
fieldGroup_
。 - 渲染字段。
- 绑定了工具提示并显示编辑器事件。
您需要处理以下情况:
onMouseDown_
CustomFields.UpgradeField.prototype.onMouseDown_ = function(e) {
// ...
};
会变为:
CustomFields.UpgradeField.prototype.showEditor_ = function() {
// ...
}
我们建议您替换 showEditor_
函数来处理鼠标点击,而不是替换 onMouseDown_
函数,因为这样可让输入通过手势系统。
如需详细了解编辑器,请参阅编辑器。
setValue
setValue
函数现在是一个模板函数,用于减少子类中的重复代码。如果您的 setValue
函数包含逻辑,请考虑对其进行重构,使其符合值处理中所述的值处理路径。
text_
建议您切勿直接访问或更新字段的 text_
属性。请改用 getText
函数访问字段的用户可读文本,并使用 setValue
函数更新字段的存储值。
如需详细了解字段的值与文本,请参阅字段剖析。
获取升级帮助
需要提供哪些信息
在寻求帮助时,最好提出具体的问题:
不建议:“此字段有什么问题?”
也不建议使用:“帮我升级此字段。”
建议:“字段文本未正确更新。”
此外,您还需要为协助您的人员提供资源。这些文件应易于他人使用。
不推荐:
- 代码图片。
- 代码不完整。
推荐:
- 以文本格式显示完整的字段代码。
- 不良现场行为的 GIF 图片。
- 重现不良字段行为的步骤。
- 您要升级的 Blockly 版本。
发布位置
在 Blockly 开发者论坛上发布升级问题。
如果您确定问题出在 Blockly 核心上,也可以在 Blockly GitHub 上发布问题。如果您决定发布问题,请填写所有必填信息。