Özel prosedür blokları oluşturmak için şunları yapmanız gerekir:
- @blockly/block-shareable-procedures'u yükleyin. eklentisine (kullanım prosedürlerinde açıklandığı gibi) öğrenin.
- Genel bakış bölümünde açıklandığı gibi, JSON serileştirme sistemini kullanın. öğrenin.
Çalışma alanına veri modelleri ekleme
Hem prosedür tanımı hem de prosedür arayan engellemeleri bir yedekleme verilerine başvuruda bulunuyor sürecin imzasını tanımlayan model (ad, parametreler ve dönüş). Bu, uygulamanızı tasarlama konusunda daha fazla esneklik sağlar (ör. prosedürlerin tek bir çalışma alanında tanımlanmasına ve başka bir) bakın.
Bu, prosedür veri modellerini çalışma alanına eklemeniz gerektiği anlamına gelir. düzgün şekilde çalışmasını sağlayın. Bunu yapmanın birçok yolu vardır (ör. kullanıcı arayüzleri).
@blockly/block-shareable-procedures, bunu
prosedür tanımlama bloklarına sahip olmak, yedek veri modellerini dinamik olarak oluşturur.
oluşturulduğundan daha kolay olur. Bunu kendiniz uygulamak için
modeli init
üzerinde oluşturup destroy
ürününde silin.
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());
}
}
Bloklarla ilgili bilgileri döndür
Prosedür tanımınız ve prosedür çağrı bloklarınızın
getProcedureModel
, isProcedureDef
ve getVarModels
yöntemleri. Bunlar,
Blockly kodunun prosedür bloklarınız hakkında bilgi almak için kullandığı kancalar.
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 [];
},
};
Güncellemelerde yeniden oluşturmayı tetikle
Prosedür tanımınız ve prosedür çağrı bloklarınızın
doProcedureUpdate
yöntemini çağırın. Bu, veri modellerinin sizi
kendilerini yeniden oluşturacak prosedür blokları bulunur.
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...
}
};
Özel serileştirme ekleme
Prosedür bloklarının serileştirilmesi iki ayrı şey yapmalıdır.
- JSON'dan yükleme yaparken bloklarınızın destekler.
- Bir prosedür bloğunu kopyalayıp yapıştırırken bloğun serileştirilmesi gerekir. kopyalanabilmesi için prosedür modelinin tüm durumunu değiştirebilirsiniz.
Bu özelliklerin ikisi de saveExtraState
ve loadExtraState
aracılığıyla işlenir.
Özel prosedür bloklarının yalnızca JSON kullanılırken desteklendiğini unutmayın
olduğundan, yalnızca JSON serileştirme kancaları tanımlamamız gerekir.
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();
}
}
}
};
İsteğe bağlı olarak prosedür modelini değiştirin
Kullanıcılara prosedür modelini değiştirme olanağı da ekleyebilirsiniz. Telefon etme
insertParameter
, deleteParameter
veya setReturnTypes
yöntemler
yeniden oluşturulması için engellemelerinizi otomatik olarak tetikler (doProcedureUpdate
aracılığıyla).
Prosedür modelini değiştirmek için kullanıcı arayüzleri oluşturma seçenekleri arasında mutatörler (ve yerleşik prosedür blokları kullanılır), tıklama işleyicilere sahip resim alanları, tamamen dışarıdadır.
Araç kutusuna blok ekleyin
Blockly'nin yerleşik dinamik prosedür kategorisi, Blockly'nin yerleşik özelliklerine özgüdür. prosedür blokları. Bloklarınıza erişmek için engellemeleri tanımlamanız gerekir. kendi özel dinamik kategorisi ve bunu ekleyin uygulayın.
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);