การสร้างการบล็อกกระบวนการที่กำหนดเองกำหนดให้คุณต้องดำเนินการดังนี้
- ติดตั้ง @blockly/block-shareable-procedures ปลั๊กอิน ตามที่อธิบายไว้ในกระบวนการใช้ หน้าเว็บ
- ใช้ระบบการเรียงอันดับ JSON ตามที่อธิบายไว้ในภาพรวม
เพิ่มโมเดลข้อมูลลงในพื้นที่ทำงาน
ทั้งคำจำกัดความของโพรเซสและการบล็อกตัวเรียกกระบวนการอ้างอิงข้อมูลสนับสนุน โมเดลที่กำหนดลายเซ็นของกระบวนการ (ชื่อ พารามิเตอร์ และ ผลลัพธ์) ซึ่งจะช่วยเพิ่มความยืดหยุ่นในการออกแบบแอปพลิเคชัน (เช่น คุณสามารถอนุญาตให้กำหนดกระบวนการในพื้นที่ทำงานเดียว และมีการอ้างอิงใน อีกรายการ)
ซึ่งหมายความว่าคุณจะต้องเพิ่มโมเดลข้อมูลกระบวนการลงในพื้นที่ทำงาน เพื่อให้การบล็อกทำงาน ซึ่งทำได้หลายวิธี (เช่น กําหนดเอง UI)
@blockly/block-shareable-procedures จะดำเนินการดังกล่าวโดย
การมีบล็อกการกำหนดกระบวนการสร้างโมเดลข้อมูลสนับสนุนแบบไดนามิก
เมื่อสร้างอินสแตนซ์ในพื้นที่ทำงาน หากต้องการดำเนินการด้วยตนเอง คุณต้อง
สร้างโมเดลใน init
แล้วลบโมเดลใน destroy
import {ObservableProcedureModel} from '@blockly/block-shareable-procedures';
Blockly.Blocks['my_procedure_def'] = {
init: function() {
this.model = new ObservableProcedureModel('default name');
this.workspace.getProcedureMap().add(model);
// etc...
}
destroy: function() {
// (Optionally) Destroy the model when the definition block is deleted.
// Insertion markers reference the model of the original block.
if (this.isInsertionMarker()) return;
this.workpace.getProcedureMap().delete(model.getId());
}
}
แสดงผลข้อมูลเกี่ยวกับการบล็อก
คำจำกัดความของกระบวนการและการบล็อกการเรียกใช้กระบวนการของคุณจําเป็นต้องใช้
เมธอด getProcedureModel
, isProcedureDef
และ getVarModels
ต่อไปนี้คือ
Hooks โค้ด Blockly ใช้ในการรับข้อมูลเกี่ยวกับการบล็อกกระบวนการ
Blockly.Blocks['my_procedure_def'] = {
getProcedureModel() {
return this.model;
},
isProcedureDef() {
return true;
},
getVarModels() {
// If your procedure references variables
// then you should return those models here.
return [];
},
};
Blockly.Blocks['my_procedure_call'] = {
getProcedureModel() {
return this.model;
},
isProcedureDef() {
return false;
},
getVarModels() {
// If your procedure references variables
// then you should return those models here.
return [];
},
};
ทริกเกอร์การแสดงผลอีกครั้งเมื่ออัปเดต
คำจำกัดความของกระบวนการและการบล็อกการเรียกใช้กระบวนการของคุณจําเป็นต้องใช้
doProcedureUpdate
วิธี นี่คือฮุกที่โมเดลข้อมูลเรียกใช้เพื่อบอก
เพื่อแสดงผลอีกครั้ง
Blockly.Blocks['my_procedure_def'] = {
doProcedureUpdate() {
this.setFieldValue('NAME', this.model.getName());
this.setFieldValue(
'PARAMS',
this.model.getParameters()
.map((p) => p.getName())
.join(','));
this.setFieldValue(
'RETURN', this.model.getReturnTypes().join(',');
}
};
Blockly.Blocks['my_procedure_call'] = {
doProcedureUpdate() {
// Similar to the def block above...
}
};
เพิ่มการเรียงลำดับแบบกำหนดเอง
การทำให้เป็นอนุกรมสำหรับบล็อกกระบวนการต้องทำ 2 สิ่งแยกกัน
- เมื่อโหลดจาก JSON บล็อกของคุณจะต้องดึงการอ้างอิงไปยัง สนับสนุนโมเดลข้อมูล เนื่องจากบล็อกและโมเดลถูกเรียงลำดับแยกกัน
- เมื่อคัดลอกและวางบล็อกกระบวนการ การบล็อกจะต้องเรียงลำดับ สถานะทั้งหมดของโมเดลกระบวนการ เพื่อให้ทำซ้ำได้
ทั้ง 2 ขั้นตอนนี้ได้รับการจัดการผ่าน saveExtraState
และ loadExtraState
โปรดทราบอีกครั้งว่าระบบจะรองรับการบล็อกกระบวนการที่กำหนดเองเมื่อใช้ JSON เท่านั้น
ระบบการทำให้เป็นอนุกรม เราจึงต้องกำหนดฮุกการเรียงอันดับ JSON เท่านั้น
import {
ObservableProcedureModel,
ObservableParameterModel,
isProcedureBlock
} from '@blockly/block-shareable-procedures';
Blockly.Blocks['my_procedure_def'] = {
// When doFullSerialization is true, we should serialize the full state of
// the model.
saveExtraState(doFullSerialization) {
const state = Object.create(null);
state['procedureId']: this.model.getId();
if (doFullSerialization) {
state['name'] = this.model.getName();
state['parameters'] = this.model.getParameters().map((p) => {
return {name: p.getName(), p.getId()};
});
state['returnTypes'] = this.model.getReturnTypes();
// Flag for deserialization.
state['createNewModel'] = true;
}
return state;
},
loadExtraState(state) {
const id = state['procedureId']
const map = this.workspace.getProcedureMap();
if (map.has(id) && !state['createNewModel']) {
// Delete the existing model (created in init).
map.delete(this.model.getId());
// Grab a reference to the model we're supposed to reference.
this.model = map.get(id);
this.doProcedureUpdate();
return;
}
// There is no existing procedure model (we are likely pasting), so
// generate it from JSON.
this.model
.setName(state['name'])
.setReturnTypes(state['returnTypes']);
for (const [i, param] of state['parameters'].entries()) {
this.model.insertParameter(
i,
new ObservableParameterModel(
this.workspace, param['name'], param['id']));
}
this.doProcedureUpdate();
},
};
Blockly.Blocks['my_procedure_call'] = {
saveExtraState() {
return {
'procedureId': this.model.getId(),
};
},
loadExtraState(state) {
// Delete our existing model (created in init).
this.workspace.getProcedureMap().delete(model.getId());
// Grab a reference to the new model.
this.model = this.workspace.getProcedureMap()
.get(state['procedureId']);
if (this.model) this.doProcedureUpdate();
},
// Handle pasting after the procedure definition has been deleted.
onchange(event) {
if (event.type === Blockly.Events.BLOCK_CREATE &&
event.blockId === this.id) {
if(!this.model) { // Our procedure definition doesn't exist =(
this.dispose();
}
}
}
};
ปรับเปลี่ยนโมเดลขั้นตอนหรือไม่ก็ได้
นอกจากนี้ คุณยังเพิ่มความสามารถสำหรับผู้ใช้ในการแก้ไขโมเดลกระบวนการได้ การโทร
insertParameter
, deleteParameter
หรือ setReturnTypes
วิธีการ
จะทริกเกอร์การบล็อกให้แสดงผลอีกครั้ง (ผ่าน doProcedureUpdate
) โดยอัตโนมัติ
ตัวเลือกสำหรับการสร้าง UI เพื่อแก้ไขโมเดลกระบวนการรวมถึงการใช้ Mutator (ซึ่ง การใช้การบล็อกขั้นตอนในตัว) ฟิลด์ภาพที่มีตัวแฮนเดิลคลิก หรือบางอย่าง อยู่นอก Blockly อย่างสิ้นเชิง ฯลฯ
เพิ่มบล็อกในกล่องเครื่องมือ
หมวดหมู่กระบวนการแบบไดนามิกในตัวของ Blockly จะเฉพาะเจาะจงสำหรับการบล็อกในแอป การบล็อกขั้นตอน ดังนั้นเพื่อให้สามารถเข้าถึงการบล็อกได้ คุณจะต้องกำหนด ไดนามิกที่กำหนดเองของคุณ หมวดหมู่ และเพิ่มหมวดหมู่ดังกล่าว ไปยังกล่องเครื่องมือ
const proceduresFlyoutCallback = function(workspace) {
const blockList = [];
blockList.push({
'kind': 'block',
'type': 'my_procedure_def',
});
for (const model of
workspace.getProcedureMap().getProcedures()) {
blockList.push({
'kind': 'block',
'type': 'my_procedure_call',
'extraState': {
'procedureId': model.getId(),
},
});
}
return blockList;
};
myWorkspace.registerToolboxCategoryCallback(
'MY_PROCEDURES', proceduresFlyoutCallback);