升級自訂欄位

在 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_;
}

阻擋自動處理:

  • 檢查新值是否與舊值不同。
  • 正在更新值。
  • 正在觸發變更事件。
  • 正在重新算繪欄位。

你需要處理:

建議升級是變更欄位 API 的位置,但如果您選擇不進行變更,欄位可能還是能正常運作。

彈性

如要進一步瞭解 EDITABLESERIALIZABLE 屬性,請參閱「可編輯和可序列化屬性」。

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_);
};

也就是說,區塊現在會自動處理:

  • 檢查欄位是否已初始化。
  • 建立 fieldGroup_
  • 轉譯欄位。
  • 繫結工具提示並顯示編輯器事件。

你需要處理:

onMouseDown_

CustomFields.UpgradeField.prototype.onMouseDown_ = function(e) {
  // ...
};

獲選:

CustomFields.UpgradeField.prototype.showEditor_ = function() {
  // ...
}

建議您覆寫 showEditor_ 函式來處理滑鼠點擊,而非 onMouseDown_ 函式,這樣可讓輸入內容傳遞通過手勢系統。

如要進一步瞭解編輯者,請參閱「編輯者」一文。

setValue

setValue 函式現在是範本函式,可減少子類別中的重複程式碼。如果您的 setValue 函式包含邏輯,請考慮重構函式,以便符合值處理中所述的值處理路徑。

text_

建議您不要直接存取或更新欄位的 text_ 屬性。請改用 getText 函式存取使用者可理解的欄位文字,並使用 setValue 函式更新欄位的儲存值。

如要進一步瞭解欄位值和欄位文字,請參閱欄位剖析

取得升級協助

提供內容

尋求協助時,建議您詢問具體問題:

不建議填寫欄位:「這個欄位有什麼問題?」

此外,也不建議填寫「協助我升級這個欄位」。

建議做法:「欄位文字未正確更新。」

此外,您也必須提供資源,協助人員取得協助。這些檔案應該要方便其他人使用,

不建議的做法:

  • 程式碼的圖片。
  • 程式碼不完整。

建議:

  • 以文字格式完整欄位代碼。
  • 呈現不良欄位行為的 GIF 圖片。
  • 重現無效欄位行為的步驟。
  • 升級的區塊版本。

發布地點

您可以在封鎖的開發人員論壇中提出升級問題。

如果您確定問題是區塊核心的問題,也可以在區塊的 GitHub 上張貼問題。如果您決定發布問題,請填寫所有必要資訊。