Как я могу создать экземпляр блока Blockly с Javascript?
Я сделал следующий блок с Blockly
в файле customBlocks.js
:
Blockly.Blocks['move_right'] = {
init: function() {
this.appendValueInput("PIXELS")
.setCheck("Number")
.appendField("move to right");
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setColour(290);
this.setTooltip('');
this.setHelpUrl('http://www.example.com/');
}
};
Blockly.JavaScript['move_right'] = function(block) {
var value_pixels = Blockly.JavaScript.valueToCode(block, 'PIXELS', Blockly.JavaScript.ORDER_ATOMIC);
// TODO: Assemble JavaScript into code variable.
var codeMoveRight = "$(\"#moveDiv\").animate({\n " +
"left: \"+=" + value_pixels + "px\"\n" +
"},1000);\n";
return codeMoveRight;
};
который перемещает a div
вправо в зависимости от того, сколько пикселей вы установили на нем. Вам нужно будет поместить блок math_number
внутри блока move_right
, чтобы поместить количество пикселей, которое вы хотите переместить.
У меня на моем html
файле a workspace
переменная, которая вводит Blockly workspace
:
var workspace = Blockly.inject('blocklyDiv',
{toolbox: document.getElementById('toolbox')});
Что я хочу сделать
Требуется извлечь из JavaScript это количество пикселей один раз, когда блок был отображен в рабочей области Blockly, а не раньше.
Что я пробовал
-
Я напрямую попытался получить доступ к переменной workspace
из консоли моего браузера (Google Chrome) и мог получить "дочерние блоки", но не значение их. Как показано ниже:
console.log(workspace.topBlocks_[0].childBlocks_);
-
Я также попытался перевести рабочее пространство в dom, а затем в текст:
var xml = Blockly.Xml.workspaceToDom(workspace);
var xml_text = Blockly.Xml.domToText(xml);
console.log(xml_text);
и здесь я вижу, что значение "дочернего блока", я имею в виду, блок math_number
, оно сохраняется в тексте, но я не знаю, как его получить.
Почему я хочу достичь этого?
Потому что я хочу, чтобы проверить, переместил ли пользователь 300 пикселей вправо. Если да, тогда я покажу сообщение, в котором я поставлю "Вы его получите!".
Мой вопрос
Есть ли возможность сделать экземпляр этого Блока, который я положил в рабочую область, а затем получить доступ к его пикселю с этим экземпляром?
EDIT:
Я также мог получить значение left
, как сказал @Oriol:
$('#moveDiv').css('left');
но я не указал его здесь, потому что он использует свойство Jquery
(это вообще не имеет значения, потому что это хороший вариант, но не так, как предполагалось). Мое намерение состоит в том, чтобы получить экземпляр Block
после того, как он положил его на Blockly workspace
, чтобы работать позже с ним в любое время.
Спасибо заранее!
Ответы
Ответ 1
Существует метод setWarningText, чтобы показать этот вид предупреждений. Вы можете изменить генератор yor следующим образом:
Blockly.JavaScript['move_right'] = function(block) {
var value_pixels = Blockly.JavaScript.valueToCode(block, 'PIXELS', Blockly.JavaScript.ORDER_ATOMIC);
// TODO: Assemble JavaScript into code variable.
var codeMoveRight = "$(\"#moveDiv\").animate({\n " +
"left: \"+=" + value_pixels + "px\"\n" +
"},1000);\n";
// You can show a blockly warning
if( value_pixels >= 300 ) block.setWarningText("You get it!");
// Or you can store its value elsewere...
// myExternalVar = value_pixels;
return codeMoveRight;
};
Это будет отображаться как значок предупреждения в самом блоке.
В любом случае, если вы хотите "запомнить" эту переменную value_pixels, я считаю, что более простой способ - сделать это в генераторе, как показано выше. Вы всегда можете сохранить его во внешнем var, доступном из ваших пользовательских функций.
EDIT:
Если вам нужно пересечь структуру блока для какой-либо другой цели, вы можете использовать:
- Blockly.mainWorkspace.getTopBlocks(true);//Чтобы получить блоки верхнего уровня
- Итерация по списку блоков верхнего уровня
- block = block.nextConnection && & block.nextConnection.targetBlock();//Чтобы "спуститься" в подблоки блока, а затем перебрать их
- if (block.type == "move_right" )...//Чтобы проверить конкретный тип блока
Я надеюсь, что это даст начальную точку, но лучший способ узнать об этих "трюках" - это чтение Blockly исходного кода. Даже когда код, как правило, хорошо комментируется, AFAIK не существует способа автогенерировать документ, и он также не доступен в Интернете.
Ответ 2
Я знаю, что этот вопрос несколько старен, но если вы все еще хотите более детальный доступ, вам следует работать с блоками IDs
(каждый блок имеет уникальный ID
).
И, чтобы получить элементы блока, не забудьте определить его имена и имена полей, чтобы вы могли ссылаться на них:
Пример блока:
Blockly.Blocks['my_block_unique_name'] = {
init: function() {
this.appendDummyInput("this_input_unique_name_for_this_block")
.appendField("this block do:")
.appendField(new Blockly.SomeField(...), "this_field_unique_name_for_this_block");
this.setColour(60);
this.setTooltip('this block do something');
}
//an crude example, be aware that blocks on fyout list will trigger it, if you did not use the block this block is disposed.
console.log(this.id);
};
Вы можете использовать событие, чтобы получить его ID
, сохранить IDs
с некоторой полезной информацией в другом месте и т.д....
И вы можете делать такие вещи, как:
mainworkspace = Blockly.mainWorkspace
block = mainworkspace.getBlockById(id);
input = block.getInput("imageInput");
// You can use `setField(newValue,name)` too in a more clean way.
input.removeField("FieldImageButton");
input.appendField(new Blockly.SomeField(...), "this_field_unique_name_for_this_block")
Итак, вы можете проанализировать блок isInFlyout
, чтобы узнать, используется ли он или нет (если это блок из открытой категории или блок, вытащенный из него, в использовании), я надеюсь, что это поможет вам и другим.