連線檢查會限制哪些連線 (以及區塊) 可以彼此連線。
連線檢查適用於模擬類型。舉例來說,以下三個區塊並未連結任何商家,因為這些區塊代表會傳回不同類型的程式碼:
連線檢查可以用來防止這類封鎖限制進行連線。如此一來,使用者就能立即取得意見回饋,避免許多簡單錯誤。
運作方式
每個連線都能與「連線檢查」建立關聯,連線檢查是可為空值的字串陣列。
如果發生下列情況,可連接兩個連線:
例如,以下兩個檢查可以連線,因為它們共用 'apple'
字串:
['apple', 'ball', 'cat']
['apple', 'bear', 'caterpillar']
不過,以下兩個檢查無法連接,因為兩者之間未共用任何字串:
['apple', 'ball', 'cat']
['ape', 'bear', 'caterpillar']
還有一個特殊情況。如果其中一個陣列是 null
,則兩個連線也可以連線。這樣做可讓您定義可以連線至任何項目的連線。
null
['ape', 'bear', 'caterpillar]
設定檢查
根據預設,所有連線都有 null
連線檢查,因此可以連線至任何項目。連線檢查必須手動指派。
連線檢查指派方式會因您使用 JSON 區塊定義或 JavaScript 區塊定義而異。
JSON
對於頂層連線,您可以直接將檢查指派給定義連線的屬性。您指派的值可以是 null
、字串 (也就是連線檢查中唯一的項目),或是字串陣列。
{
'type': 'custom_block',
'output': null,
'nextStatement': 'a connection check entry',
'previousStatement': ['four', 'connection', 'check', 'entries']
}
對於輸入內容,您可以將檢查指派給輸入定義的 check
屬性。如果 check
屬性不存在,系統會將檢查視為 null
。您指派的值可以是字串或字串陣列。
{
'type': 'custom_block',
'message0': '%1 %2',
'args0': [
{
'type': 'input_value',
'check': 'a connection check entry'
},
{
'type': 'input_statement',
'check': ['four', 'connection', 'check', 'entries']
}
]
}
JavaScript
如果是頂層連線,您可以將檢查直接傳遞至定義連線的方法。如未傳遞值,系統會將檢查視為 null
。您傳遞的值可以是字串 (變成連線檢查中唯一的項目) 或字串陣列。
Blockly.Blocks['custom_block'] = {
init: function() {
this.setOutput(true); // null check
this.setNextStatement(true, 'a connection check entry');
this.setPreviousStatement(true, ['four', 'connection', 'check', 'entries']);
}
}
針對輸入內容,您可以在定義輸入內容後將檢查傳送至 setCheck
方法。如未呼叫 setCheck
方法,系統會將檢查視為 null
。您傳遞的值可以是字串或字串陣列。
Blockly.Blocks['custom_block'] = {
init: function() {
this.appendValueInput('NAME')
.setCheck('a connection check entry');
this.appendStatementInput('NAME')
.setCheck(['four', 'connection', 'check', 'entries']);
}
}
內建檢查字串
內建區塊會使用 'Array'
、'Boolean'
、'Colour'
、'Number'
和 'String'
值進行連線檢查。如果您希望區塊與內建區塊互通,可以使用這些值使區塊相容。
值範例
定義輸入和輸出的連線檢查時,通常您應將檢查視為代表類型。
輸入內容的檢查應包含其接受的每個「類型」,而輸出的檢查應包含「完全」這些「傳回」的內容。
接受單一類型
在最基本的情況下,如要建立「接受」或「傳回」一種類型的區塊,您必須在連線的連線檢查中加入該類型。
接受多種類型
如要建立「接受」多種類型的區塊,您需要在輸入的連線檢查中納入所有可接受的類型。
依照慣例,如果輸出「有時」可以於多個情況下接受 (例如,如果您允許有時將數字做為字串使用),輸出的限制應更嚴格,輸入的值也應較為寬鬆。這項慣例可確保輸出不會連接不受支援的輸出。
接受任何類型
如要建立「接受」任何類型的區塊,您必須將輸入的連線檢查設為 null
。
傳回子類型
如要建立可「傳回」子類型的區塊,您必須在輸出的連線檢查中一併包含類型和超級類型。
如果是子類型,輸出檢查可以進行多次檢查,因為區塊「一律」會「傳回」這兩種類型。
傳回參數化類型
如要建立「傳回」參數化類型的區塊,您需要在輸出的連線檢查中同時加入參數化版本和未參數化版本。
視所需的區塊語言嚴格程度而定,建議您也加入類型的變異數。
和子類型一樣,在這個範例中,輸出檢查可以進行多次檢查,因為區塊「一律」會「傳回」這兩種類型。
堆疊或陳述式範例
開發人員有幾種常見的方式,可以定義先前和下一個連線的檢查項目。您通常可以想成是限制區塊的排序方式,
下一個連線應包含哪些區塊應遵循目前的區塊,先前的連線則包含目前區塊「是」。
依序保留區塊
如要建立一組按照已定義順序連線的區塊,您需要在下一次連線檢查中納入哪些區塊應遵循目前區塊,以及上次連線檢查中的目前區塊「是」。
允許許多中間區塊
如要建立允許大量中間區塊的已排序區塊,您必須在中間區塊的下一個連線檢查中,納入至少一個中間區塊的連線檢查項目。這樣就能讓區塊跟其本身有更多路徑。
不允許中間區塊
如要建立一組已排序的區塊,且中間區塊為選用項目,您必須加入至少一個中間區塊的先前連線檢查項目,以及在第一個區塊的下一個連線檢查中,加入最後一個區塊的上一個連線檢查項目。如此一來,第一個區塊後面會接著一個中間區塊或最後一個區塊。
任一或堆疊
如要建立只能從某個群組後面接續的區塊,或封鎖另一個群組中的區塊 (而非兩者),您必須執行兩項操作:
在第一個區塊的下一個連線檢查中,您需要在第一個區塊的下一個連線檢查中,納入至少一個先前連線檢查項目的項目。
您需要定義群組的下一次連線檢查,僅納入先前連線檢查中的值 (因此這些值只能後面接有相同群組的區塊)。
限制
這個系統相當強大,可以解決許多用途,但有一些限制。
限制更多背景資訊
這個系統本身不支援限制可連線的「更完整的背景資訊」。例如,您無法說 break
區塊只能在 loop
區塊內存在。連線檢查系統僅會將兩個連線列入考量。
如要支援這項功能,您「可以」使用事件系統監聽區塊移動事件,並檢查區塊位置是否有誤。
Blockly.Blocks['custom_block'] = {
init: function() { }
onchange: function(e) {
if (this.workspace.isDragging()) return;
if (e.type !== Blockly.Events.BlockMove) return;
if (!this.getSurroundLoop()) this.outputConnection.disconnect();
}
loopTypes: new Set(); // Your valid *block types* (not connection checks).
getSurroundLoop: function () {
let block = this.getSurroundParent();
do {
if (loopTypes.has(block.type)) return block;
block = block.getSurroundParent();
} while (block);
return null;
},
}
一般類型
這個系統本身不支援定義一般類型。例如,您無法建立「Identity」區塊,該區塊會「傳回」的任何輸入內容。
您可以藉由主動變更區塊輸出連線檢查,使其與其輸入內容相符,藉此支援這種情況。您可以使用事件系統監聽封鎖移動事件。
Blockly.Blocks['custom_block'] = {
init: function() { }
onchange: function(e) {
if (e.type !== Blockly.Events.BlockMove) return;
this.setOutput(
true, this.getInputTargetBlock()?.outputConnection.getCheck());
}
}
但如果連結區塊「也」一般,則無法正常運作。無法解決這個問題。
連線檢查工具
如果這個系統不適用於您的使用情境,您也可以建立自訂連線檢查工具,以變更連線檢查的比較方式。
舉例來說,如果您想要建立更進階的系統,以便處理這種系統的部分限制,可以建立自訂連線檢查工具。