定義區塊

區塊定義是指區塊的外觀和行為,包括文字 選擇顏色、形狀以及連接的其他方塊

JSON 格式與 JavaScript API 的比較

Blockly 有兩種定義區塊的方法:JSON 物件和 JavaScript 函式。 JSON 格式旨在簡化本地化作業 相關程序 適合用不同字詞排序的語言建議使用 JSON 格式 定義區塊的方法

不過,JSON 格式無法直接定義進階功能,例如 以變更者或驗證工具為例這些程式碼必須以 JavaScript 編寫,一般為 extensions

使用 Blockly 原始 JavaScript 實作的應用程式也可以寫入 直接封鎖較低層級的 Blockly API 函式呼叫定義,如 當中各種 JavaScript 範例

JSON

Blockly.defineBlocksWithJsonArray([{
  "type": "string_length",
  "message0": 'length of %1',
  "args0": [
    {
      "type": "input_value",
      "name": "VALUE",
      "check": "String"
    }
  ],
  "output": "Number",
  "colour": 160,
  "tooltip": "Returns number of letters in the provided text.",
  "helpUrl": "http://www.w3schools.com/jsref/jsref_length_string.asp"
}]);

JavaScript

Blockly.Blocks['string_length'] = {
  init: function() {
    this.appendValueInput('VALUE')
        .setCheck('String')
        .appendField('length of');
    this.setOutput(true, 'Number');
    this.setColour(160);
    this.setTooltip('Returns number of letters in the provided text.');
    this.setHelpUrl('http://www.w3schools.com/jsref/jsref_length_string.asp');
  }
};

init 函式會建立區塊形狀。在這裡 函式,關鍵字 this 即是實際建立的區塊。

這兩個範例都載入相同的「string_length」封鎖。

在網站上,系統會使用 initJson 函式載入 JSON 格式。 這也允許在 Blockly 網頁上混用這兩種格式。是 並使用 JSON 定義區塊 僅適用於 JSON 不支援的區塊定義部分

以下是主要使用 JSON 定義的區塊範例 但是使用 JavaScript API 擴充以提供動態工具提示。

JavaScript

var mathChangeJson = {
  "message0": "change %1 by %2",
  "args0": [
    {"type": "field_variable", "name": "VAR", "variable": "item", "variableTypes": [""]},
    {"type": "input_value", "name": "DELTA", "check": "Number"}
  ],
  "previousStatement": null,
  "nextStatement": null,
  "colour": 230
};

Blockly.Blocks['math_change'] = {
  init: function() {
    this.jsonInit(mathChangeJson);
    // Assign 'this' to a variable for use in the tooltip closure below.
    var thisBlock = this;
    this.setTooltip(function() {
      return 'Add a number to variable "%1".'.replace('%1',
          thisBlock.getFieldValue('VAR'));
    });
  }
};

色塊顏色

區塊的主要顏色是由 JSON colour 屬性定義, block.setColour(..) 函式, 或使用主題定義區塊 。

JSON

{
  // ...,
  "colour": 160,
}

JavaScript

init: function() {
  // ...
  this.setColour(160);
}

請參閱區塊顏色指南 ,掌握更多詳細資訊。

陳述式連線

使用者可使用 nextStatementpreviousStatement 個連接器。在 Blockly 的標準版面配置中,這些連線 位於頂端和底部,而區塊則垂直堆疊。

帶有前一個連接器的區塊不得含有 輸出連接器,反之亦然。「陳述式區塊」一詞 指的是沒有輸出值的區塊。陳述式區塊通常會包含 包括先前連線和另一個連線

nextStatementpreviousStatement 連線可 typed、 但標準區塊不會採用這項功能

下一個連線

在區塊底部建立點, 。原本沒有連線卻未連線的區塊 通常代表事件,且可以設定為 帽子

JSON

未輸入:

{
  ...,
  "nextStatement": null,
}

類型 (很少):

{
  "nextStatement": "Action",
  ...
}

JavaScript

未輸入:

this.setNextStatement(true);  // false implies no next connector, the default

類型 (很少):

this.setNextStatement(true, 'Action');

上一個連線

在區塊頂端建立凹槽,以便連接成堆疊 陳述這句話。

先前的連線無法建立輸出連線。

JSON

未輸入:

{
  ...,
  "previousStatement": null,
}

類型 (很少):

{
  "previousStatement": "Action",
  ...
}

JavaScript

未輸入:

this.setPreviousStatement(true);  // false implies no previous connector, the default

類型 (很少):

this.setPreviousStatement(true, 'Action');

區塊輸出

區塊可能只有一個輸出內容,以其 開頭。輸出結果會連結至值輸入內容。具有輸出內容的區塊 通常稱為值區塊

JSON

未輸入:

{
  // ...,
  "output": null,
}

輸入:

{
  // ...,
  "output": "Number",
}

JavaScript

未輸入:

init: function() {
  // ...
  this.setOutput(true);
}

輸入:

init: function() {
  // ...
  this.setOutput(true, 'Number');
}

具有輸出連接器的區塊也不能有先前的陳述式凹口。

封鎖輸入來源

區塊包含一或多個輸入內容,其中每個輸入內容都具有一系列 欄位,且可能在連線中。以下提供 多種內建輸入內容類型

  • 值輸入:連線至 輸出連線 值區塊math_arithmetic 區塊 (加法、減法) 是 這裡會顯示兩個值輸入的區塊範例
  • 敘述輸入資料:會連結至 陳述式區塊連結。 when 迴圈的巢狀部分是陳述式輸入的一個範例。
  • 虛擬輸入:沒有區塊連線。就像換行是全新的 區塊已設為使用外部值輸入
  • 結束資料列輸入:未建立區塊連結,且一律會像 。

您也可以建立自訂輸入資料,藉此支援自訂輸入欄位。 轉譯

JSON 格式和 JavaScript API 使用的模型略有不同 輸入內容

JSON 格式的輸入和欄位

JSON 定義的模塊結構為內插式序列 訊息字串 ( message0message1、...),其中每個內插符記 (%1%2、...) 是欄位或輸入結尾 (也就是輸入連接器 會在相符的 JSON argsN 陣列中顯示。格式為 目的是簡化國際化程序

JSON

{
  "message0": "set %1 to %2",
  "args0": [
    {
      "type": "field_variable",
      "name": "VAR",
      "variable": "item",
      "variableTypes": [""]
    },
    {
      "type": "input_value",
      "name": "VALUE"
    }
  ]
}

內插符記必須與 args0 陣列完全相符:沒有重複項目、 不會遺漏任何資料符記可按任意順序顯示,因此 變更區塊版面配置。

內插符記任一側的文字為空白字元。 使用 % 字元的文字 (例如參照百分比時) 應使用 %% 的情況下,系統就不會將其解讀為內插符記。

引數和引數類型的順序會定義 封鎖。變更其中一個字串可能會完全改變區塊的版面配置。 在字詞順序不同的語言中,這一點尤其重要 而不是英文。假設在以下假設語言中,"set %1 to %2" (如已使用) 就需要反轉,才能表示 "put %2 in %1"。變更中 並保留其餘 JSON 內容 會產生以下區塊:

自動變更欄位的順序、建立虛擬輸入 以及從外部切換至內部輸入來源。

同時自動取代訊息中的任何換行字元 (\n) 字串做為結尾。

JSON

{
  "message0": "set %1\nto %2",
  "args0": [
    {
      "type": "field_variable",
      "name": "VAR",
      "variable": "item",
      "variableTypes": [""]
    },
    {
      "type": "input_value",
      "name": "VALUE"
    }
  ]
}

ARG

每個訊息字串都會與數字相同的 args 陣列配對。適用對象 例如,message0 帶有 args0。內插符記 (%1%2、...) 參照 args 陣列的項目。每個物件都有 type 字串。其他參數會因類型而異:

您也可以定義自己的自訂欄位自訂輸入內容並做為引數傳遞。

每個物件也可能有 alt 欄位。如果 Blockly 並未 無法識別物件的 type,那麼系統則會在其定位使用 alt 物件。適用對象 例如,如果在 Blockly 中加入名為 field_time 的新欄位,則會使用 這個欄位可以使用 alt 定義舊版的 field_input 備用資料 部分區塊:

JSON

{
  "message0": "sound alarm at %1",
  "args0": [
    {
      "type": "field_time",
      "name": "TEMPO",
      "hour": 9,
      "minutes": 0,
      "alt":
        {
          "type": "field_input",
          "name": "TEMPOTEXT",
          "text": "9:00"
        }
    }
  ]
}

alt 物件可能有專屬的 alt 物件,因此允許鏈結。 最後,如果 Blockly 無法在 args0 陣列中建立物件 ( 嘗試任何 alt 物件),系統就會直接略過該物件。

如果 message 字串結尾為文字或欄位,但輸入中未包含這些欄位。 因此,如果區塊的最後一個輸入內容是虛擬輸入內容,就有可能省略 args 陣列,而且不需要內插至 message。 自動加入尾隨虛擬輸入,讓翻譯人員可以 message,無須修改 JSON 的其餘部分。請參閱 "set %1 to %2" (無虛擬輸入內容) 和 "put %2 in %1" (已新增虛擬輸入) 請參閱本頁前文中的說明

implicitAlign0

在極少數情況下,自動建立的結尾虛擬輸入內容需要對齊 至 "RIGHT""CENTRE"。如未指定,則預設值為 "LEFT"

在以下範例中,message0"send email to %1 subject %2 secure %3" 和 Blockly 會自動在第三列新增虛擬輸入。設定 implicitAlign0 設為 "RIGHT" 會強制這個列靠右對齊。這個 未明確定義的所有輸入項目都會套用對齊規則 區塊定義,包括會取代換行字元的結束列輸入內容 ('\n')。還有已淘汰的屬性 lastDummyAlign0 行為與 implicitAlign0 相同

設計 RTL (阿拉伯文和希伯來文) 區塊時,左右移動會反轉。 因此,"RIGHT" 會將欄位靠左對齊。

message1args1implicitAlign1

有些區塊會自然區分為兩個以上的獨立部分。 請考慮這個重複區塊,其中包含兩個資料列:

如果這個區塊是以單一訊息描述,message0 屬性 應為 "repeat %1 times %2 do %3"。對譯者來說,這個字串很尷尬 但很難解釋 %2 替代的意思。「%2」虛擬 而且有時候可能不需要輸入某些語言此外, 想要分享第二列文字的區塊。更好的方法 代表 JSON 使用多個訊息和引數屬性:

JSON

{
  "type": "controls_repeat_ext",
  "message0": "repeat %1 times",
  "args0": [
    {"type": "input_value", "name": "TIMES", "check": "Number"}
  ],
  "message1": "do %1",
  "args1": [
    {"type": "input_statement", "name": "DO"}
  ],
  "previousStatement": null,
  "nextStatement": null,
  "colour": 120
}

可定義任意數量的 messageargsimplicitAlign 屬性 且從 0 開始,依序遞增。請注意, Block Factory 無法將訊息分割為多個部分, 很簡單吧!

JavaScript 中的輸入和欄位

JavaScript API 為每個輸入類型提供 append 方法:

JavaScript

this.appendEndRowInput()
    .appendField('for each')
    .appendField('item')
    .appendField(new Blockly.FieldVariable());
this.appendValueInput('LIST')
    .setCheck('Array')
    .setAlign(Blockly.inputs.Align.RIGHT)
    .appendField('in list');
this.appendStatementInput('DO')
    .appendField('do');
this.appendDummyInput()
    .appendField('end');

每個附加方法都可接受一個 ID 字串,供程式碼產生器使用。虛擬 和結束資料列輸入內容很少需要參照,且 ID 通常位於左側 未設定。

JavaScript API 也包含用於附加作業的通用 appendInput 方法 自訂輸入內容請注意,在此情況下,ID 應該 直接傳遞至自訂輸入的建構函式。

JavaScript

this.appendInput(new MyCustomInput('INPUT_NAME'))
    .appendField('an example label')

所有 appendInput 方法 (通用和非一般方法) 都會傳回 輸入物件,以便使用方法鏈結進一步設定這些物件。有 是三個用來設定輸入的內建方法。

setCheck

JavaScript

input.setCheck('Number');

這個選用函式會用於檢查連接的輸入。如果提供了 空值的引數 (預設值),然後將這個輸入內容連結到任何區塊。 詳情請參閱類型檢查

setAlign

JavaScript

input.setAlign(Blockly.inputs.Align.RIGHT);

這個選用函式可用來對齊欄位 (請見下方說明)。在架構中 自我描述性值可能會做為引數傳遞至這個函式: Blockly.inputs.Align.LEFTBlockly.inputs.Align.RIGHTBlockly.inputs.Align.CENTER

設計 RTL (阿拉伯文和希伯來文) 區塊時,左右移動會反轉。 因此,Blockly.inputs.Align.RIGHT 會將欄位靠左對齊。

appendField

建立輸入內容並附加至含有 appendInput 的區塊後, 可選擇在輸入中附加任意數量的「欄位」。這些欄位 這些詞彙經常做為標籤 說明各項輸入內容的用途

JavaScript

input.appendField('hello');

最簡單的欄位元素是文字。封鎖規則的慣例是 小寫文字,但專有名稱除外 (例如 Google、SQL)。

輸入列可包含任意數量的欄位元素。多個appendField 呼叫可能會鏈結在一起,以便有效率地將多個欄位新增至同一個 輸入列

JavaScript

input.appendField('hello')
     .appendField(new Blockly.FieldLabel('Neil', 'person'));

appendField('hello') 呼叫實際上是使用明確指令的捷徑 FieldLabel 建構函式:appendField(new Blockly.FieldLabel('hello'))。 只有在指定 類別名稱,以便使用 CSS 規則設定文字樣式。

內嵌與外部

區塊輸入內容可以算繪為外部或內部。

區塊定義可指定選用的布林值,以控制輸入內容 無論是否為內嵌內容如果為 false,則任何輸入的值皆為外部 (例如 左區塊)。如果值為 true,則任何輸入的值都會內嵌 (例如 右區塊)。

JSON

{
  // ...,
  "inputsInline": true
}

JavaScript

init: function() {
  // ...
  this.setInputsInline(true);
}

如未定義,Blockly 會使用一些經驗法則來猜測 最佳。假設 Blockly 是正確的選擇,請將這個欄位保留未定義 協助翻譯不同語言的資料 支援多種模式請參閱 "set %1 to %2" 的 JSON 範例 (外部輸入內容) "put %2 in %1" (內嵌輸入內容)。

如果區塊可能含有少量輸入資料 (例如數字),請使用內嵌輸入內容。 如果 collapse,使用者可以透過內容選單切換這個選項。 設定就會啟用 (如果工具箱含有類別,則預設為 true)。

欄位

欄位會定義區塊中的大部分 UI 元素。其中包括 字串標籤、圖片和輸入內容 常值資料 例如字串和數字最簡單的範例是 math_number 區塊 使用 field_input 讓使用者輸入數字。

欄位會透過 appendField.

Blockly 提供多種內建欄位,包括文字輸入、顏色挑選器 和圖片您也可以自行建立欄位。

→ 進一步瞭解內建欄位

→ 進一步瞭解如何建立自訂欄位

圖示

圖示會在表面為「meta」的區塊上定義 UI 元素關於 封鎖。

系統會使用 addIcon 將圖示附加到區塊中。

Blockly 提供多種內建圖示,包括註解圖示 和警告圖示您也可以建立自己的圖示。

→ 進一步瞭解如何建立自訂圖示

工具提示

使用者將滑鼠遊標懸停在區塊上時,工具提示可提供即時說明。 如果文字過長,系統會自動換行。

JSON

{
  // ...,
  "tooltip": "Tooltip text."
}

JavaScript

init: function() {
  this.setTooltip("Tooltip text.");
}

在 JavaScript API 中,您也可以將工具提示定義為函式,而非 靜態字串。這有助於提供動態協助。請參閱 math_arithmetic: 工具提示範例,視先前提供的下拉式選單選項而定

JavaScript

Blockly.Blocks['math_arithmetic'] = {
  init: function() {
    // ...

    // Assign 'this' to a variable for use in the tooltip closure below.
    var thisBlock = this;
    this.setTooltip(function() {
      var mode = thisBlock.getFieldValue('OP');
      var TOOLTIPS = {
        'ADD': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_ADD,
        'MINUS': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MINUS,
        'MULTIPLY': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MULTIPLY,
        'DIVIDE': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_DIVIDE,
        'POWER': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_POWER
      };
      return TOOLTIPS[mode];
    });
  }
};

使用 JavaScript API 時,區塊可以指定函式,而非靜態 字串,傳回工具提示字串。這允許動態工具提示。 如需範例,請參閱 math_arithmetic

自訂

您也可以透過提供自訂顯示功能,自訂工具提示的外觀 函式。建立可接受兩個參數的函式:

  • 第一個是 <div> 元素,用於算繪內容
  • 第二,當滑鼠遊標移到按鈕上時 的工具提示

在函式主體中,您可以在函式主體中, div如果要讓滑鼠遊標懸停在區塊上定義的工具提示字串,您可以 呼叫 Blockly.Tooltip.getTooltipOfObject(element);,其中 element 是 。

最後,請註冊此函式,讓 Blockly 在適當時機呼叫此函式:

Blockly.Tooltip.setCustomTooltip(yourFnHere);

如需範例,請參閱 自訂工具提示示範

說明網址

封鎖後可能會有相關聯的說明頁面。這可供 「封鎖網頁」使用者,請在封鎖方塊上按一下滑鼠右鍵,然後選取「說明」 我們要使用相關內容選單如果這個值是 null,選單就會呈現灰色。 。

JSON

{
  // ...,
  "helpUrl": "https://en.wikipedia.org/wiki/For_loop"
}

JavaScript

init: function() {
  // ...
  this.setHelpUrl('https://en.wikipedia.org/wiki/For_loop');
}

使用 JavaScript API 時,區塊可以指定函式,而非靜態 字串,因此會傳回網址字串,因此可提供動態說明。

變更事件監聽器和驗證工具

區塊可包含變更接聽程式函式時,可呼叫這些函式, 工作區 (包括與區塊無關的條件)這類 API 主要用於 設定封鎖文字,或設定封鎖外的類似使用者通知 工作區

這個函式是透過函式呼叫 setOnChange 的新增作業 初始化期間,如果想使用 JSON 擴充功能 在所有平台上

JSON

{
  // ...,
  "extensions":["warning_on_change"],
}

Blockly.Extensions.register('warning_on_change', function() {
  // Example validation upon block change:
  this.setOnChange(function(changeEvent) {
    if (this.getInput('NUM').connection.targetBlock()) {
      this.setWarningText(null);
    } else {
      this.setWarningText('Must have an input block.');
    }
  });
});

JavaScript

Blockly.Blocks['block_type'] = {
  init: function() {
    // Example validation upon block change:
    this.setOnChange(function(changeEvent) {
      if (this.getInput('NUM').connection.targetBlock()) {
        this.setWarningText(null);
      } else {
        this.setWarningText('Must have an input block.');
      }
    });
  }
}

系統會呼叫函式並傳入 變更事件。 在函式中,this 是指區塊例項。

由於函式會在任何變更時呼叫,因此如有變更,開發人員必須確保 監聽器會快速執行同時留意工作區的變更 可能會串聯或循環回事件監聽器

請參閱《controls_flow_statements》、《logic_compare》和《procedures_ifreturn》 區塊範例

請注意,可編輯的欄位各有用於輸入驗證的事件監聽器 並引發副作用

變動者

變動器允許進階模塊變更形狀,最值得注意的是 使用者開啟對話方塊以新增、移除或重新排列元件。變動器可以是 使用 mutator 鍵透過 JSON 新增。

JSON

{
  // ...,
  "mutator":"if_else_mutator"
}

個別區塊設定

區塊執行個體有許多屬性,可設定其運作方式 使用者。您可以根據這些資料限制工作區, 網域的屬性 (例如只有一個「開始」事件),或焦點 使用者的努力 (例如教學課程)。

可刪除狀態

block.setDeletable(false);

如果設為 False,使用者就無法刪除封鎖條件。封鎖預設值 可刪除成可編輯的工作區

任何區塊 (包括復原的區塊) 都可以程式設計方式刪除:

block.dispose();

可編輯狀態

block.setEditable(false);

如果設為 False,使用者將無法變更區塊的欄位 (例如下拉式選單和文字輸入)。封鎖預設為可編輯的編輯 工作區

可移動狀態

block.setMovable(false);

如果設為 False,使用者將無法直接移動區塊。一個 如果是其他區塊的子項,即不可移除的區塊,系統可能無法與 這個區塊會隨著父項移動而移動阻攻次數 預設為可移動的工作區。

只要區塊位於 工作區

block.moveBy(dx, dy)

工作區區塊的起始位置預設為 (0, 0)。

封鎖資料

this.data = '16dcb3a4-bd39-11e4-8dfc-aa07a5b093db';

資料是附加至區塊的選用字串。當 資料字串序列化,會以該字串序列化。包括 區塊相同或複製/貼上

通常用於將區塊與外部資源建立關聯。

序列化到 JSON 時,資料會在區塊中儲存為頂層屬性:

{
  "type": "my_block",
  "data": "16dcb3a4-bd39-11e4-8dfc-aa07a5b093db",
  // etc..
}

將資料字串序列化為 XML (舊冰箱序列化系統) 時,資料字串 會儲存在區塊中的 <data></data> 標記中:

<block type="my_block">
  <data>16dcb3a4-bd39-11e4-8dfc-aa07a5b093db</data>
  <!-- etc... -->
</block>

破壞

區塊具有 destroy 掛鉤,從 工作區這可用來刪除所有備份資料模型/外部 與不再需要的區塊相關聯的資源

JSON

{
  // ...,
  "extensions":["destroy"],
}

Blockly.Extensions.registerMixin('destroy', {
  destroy: function() {
    this.myResource.dispose();
  }
});

JavaScript

Blockly.Blocks['block_type'] = {
  destroy: function() {
    this.myResource.dispose();
  }
}

釋放區塊的父項之後,會呼叫 destroy 方法,但 以免任何子項或欄位遭到棄置。

內容選單

根據預設,封鎖功能會在右鍵顯示內容選單,讓使用者執行操作 例如新增註解或重複區塊

如要停用個別區塊的內容選單,請按照下列步驟操作:

block.contextMenu = false;

您也可以自訂選單中顯示的選項。如要自訂 請參閱 內容選單說明文件。 如要自訂個別區塊的選單,可以 customContextMenu。這個函式採用一系列選單選項 現有的變更,也就是說,您可以同時新增及移除項目。

每個選單選項都是一個物件,其中包含三個屬性:

  • text 是顯示文字。
  • enabled 為布林值。如果停用這個選項,這個選項仍會顯示,但以灰色顯示 文字。
  • callback 是點選選項時要呼叫的函式。