확장 프로그램 및 음소거기

확장은 블록이 사용되므로 특정 유형의 각 블록에서 실행되는 함수입니다. 생성됨. 이는 종종 블록에 맞춤 구성 또는 동작을 추가합니다.

변형자는 맞춤 직렬화를 추가하고 블록에 추가되기도 했습니다.

확장 프로그램

확장은 블록이 사용되므로 특정 유형의 각 블록에서 실행되는 함수입니다. 생성됨. 사용자는 맞춤 구성을 추가 (예: 블록의 도움말 설정)하거나 맞춤 동작 (예: 블록에 이벤트 리스너 추가)

// This extension sets the block's tooltip to be a function which displays
// the parent block's tooltip (if it exists).
Blockly.Extensions.register(
    'parent_tooltip_extension',
    function() { // this refers to the block that the extension is being run on
      var thisBlock = this;
      this.setTooltip(function() {
        var parent = thisBlock.getParent();
        return (parent && parent.getInputsInline() && parent.tooltip) ||
            Blockly.Msg.MATH_NUMBER_TOOLTIP;
      });
    });

확장 프로그램은 '등록'되어야 합니다. 문자열과 연결될 수 있도록 키를 누릅니다. 그런 다음 이 문자열 키를 앱의 extensions 속성에 할당할 수 있습니다. 블록 유형의 JSON 정의에서 확장자를 추가합니다.

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

여러 광고 확장을 한 번에 추가할 수도 있습니다. extensions는 확장 프로그램을 하나만 적용하는 경우에도 속성은 배열이어야 합니다.

{
  //...,
  "extensions": ["parent_tooltip_extension", "break_warning_extension"],
}

믹스인

또한 블록은 일부 속성/도우미 함수를 블록에 추가하고 즉시 실행하지는 않습니다. 이 mixin 속성을 등록하여 객체에는 추가 속성/메서드가 모두 포함됩니다. 믹스인 객체 함수가 입력될 때마다 믹스인을 적용하는 함수로 래핑됩니다. 지정된 블록 유형이 생성됩니다.

Blockly.Extensions.registerMixin('my_mixin', {
  someProperty: 'a cool value',

  someMethod: function() {
    // Do something cool!
  }
))`

믹스인과 연결된 문자열 키는 다른 믹스인과 마찬가지로 JSON에서 참조할 수 있습니다. 확장자가 포함됩니다.

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

변형자

뮤테이터는 추가 직렬화 (추가 상태를 블록에 추가합니다. 예를 들어 내장 controls_iflist_create_with 블록에는 추가 직렬화가 필요하므로 얼마나 많은 입력이 있는지 저장할 수 있습니다.

블록의 모양을 변경한다고 해서 반드시 블록의 모양을 변경해야 하는 것은 아닙니다. 추가 직렬화가 필요합니다. 예를 들어 math_number_property 블록은 값이 이미 있는 드롭다운 필드를 기반으로 이를 실행합니다. 직렬화됩니다. 따라서 유효성 검사 도구로는 뮤테이터가 필요합니다.

자세한 내용은 직렬화 페이지에 대한 뮤테이터가 필요한 경우와 필요하지 않은 경우에 대한 자세한 정보를 제공합니다.

또한 변형자는 블록의 모양을 변경할 수 있도록 기본 제공 UI를 제공합니다. 몇 가지 선택적 메서드를 제공합니다.

직렬화 후크

뮤테이터에는 함께 작동하는 두 쌍의 직렬화 후크가 있습니다. 후크 1쌍 다른 한 쌍은 새로운 JSON 직렬화 시스템과 호환되고 다른 쌍은 이전 XML 직렬화 시스템입니다. 이 쌍 중 하나 이상을 제공해야 합니다.

SaveExtraState 및 loadExtraState

saveExtraStateloadExtraState는 새로운 JSON 직렬화 시스템입니다. saveExtraState는 직렬화 가능한 JSON을 반환합니다. 블록의 추가 상태를 나타내는 값 loadExtraState 직렬화 가능한 동일한 JSON 값을 받아 블록에 적용합니다.

// These are the serialization hooks for the lists_create_with block.
saveExtraState: function() {
  return {
    'itemCount': this.itemCount_,
  };
},

loadExtraState: function(state) {
  this.itemCount_ = state['itemCount'];
  // This is a helper function which adds or removes inputs from the block.
  this.updateShape_();
},

결과 JSON은 다음과 같습니다.

{
  "type": "lists_create_with",
  "extraState": {
    "itemCount": 3 // or whatever the count is
  }
}
상태 없음

블록이 직렬화될 때 기본 상태가 되면 saveExtraState 메서드는 null를 반환하여 이를 나타낼 수 있습니다. 만약 saveExtraState 메서드가 null를 반환하면 extraState 속성이 추가되지 않습니다. JSON입니다 이렇게 하면 저장 파일 크기가 작아집니다.

전체 직렬화 및 지원 데이터

saveExtraState는 선택적 doFullSerialization 매개변수도 수신합니다. 이 다른 시스템에 의해 직렬화된 상태를 참조하는 블록에서 사용됩니다. 직렬화 (예: 데이터 모델 지원) 매개변수는 블록이 역직렬화되면 참조된 상태를 사용할 수 없으므로 블록은 모든 지원 상태 자체를 직렬화해야 합니다. 예를 들어 개별 블록이 직렬화되거나 블록을 복사하여 붙여넣은 경우 true를 반환합니다.

이에 대한 두 가지 일반적인 사용 사례는 다음과 같습니다.

  • 개별 블록이 지원 데이터가 저장되는 작업공간에 로드될 때 존재하지 않는 경우 자체 상태로 충분한 정보를 가지고 있어 새 데이터 모델을 만듭니다
  • 블록을 복사하여 붙여넣으면 항상 새 백업이 생깁니다. 기존 모델을 참조하는 대신 해당 모델을 사용합니다.

이를 사용하는 일부 블록은 @blockly/block-shareable-procedures에 포함된 부분을 참조하세요. 정상 상태를 저장하는 지원 데이터 모델에 대한 참조를 직렬화합니다. 그러나 doFullSerialization 매개변수가 true이면 확인할 수 있습니다 공유 가능한 절차 블록은 이를 사용하여 복사하여 붙여넣는 대신 새 지원 데이터 모델을 만듭니다. 생성합니다.

VariantToDom 및 domToMutation

mutationToDomdomToMutation는 이전 XML 직렬화 시스템입니다. 필요한 경우에만 이 후크를 사용하세요 (예: 아직 마이그레이션되지 않은 이전 코드베이스에서 작업하는 경우)하지 않으면 saveExtraStateloadExtraState.

mutationToDom는 다음 객체의 추가 상태를 나타내는 XML 노드를 반환합니다. 동일한 XML 노드를 수락하고 상태를domToMutation 차단하세요.

// These are the old XML serialization hooks for the lists_create_with block.
mutationToDom: function() {
  // You *must* create a <mutation></mutation> element.
  // This element can have children.
  var container = Blockly.utils.xml.createElement('mutation');
  container.setAttribute('items', this.itemCount_);
  return container;
},

domToMutation: function(xmlElement) {
  this.itemCount_ = parseInt(xmlElement.getAttribute('items'), 10);
  // This is a helper function which adds or removes inputs from the block.
  this.updateShape_();
},

결과 XML은 다음과 같습니다.

<block type="lists_create_with">
  <mutation items="3"></mutation>
</block>

mutationToDom 함수가 null을 반환하면 추가 요소는 XML에 추가됩니다.

UI 후크

뮤테이터의 일부로 특정 함수를 제공하면 Blockly는 기본 '뮤테이터' UI를 추가하는 것입니다.

직렬화를 추가하려는 경우 이 UI를 사용하지 않아도 됩니다. 다음과 같은 방법을 사용할 수 있습니다. 블록 더하기-빼기 기호와 같은 플러그인 UI를 사용하지 않을 수도 있습니다.

구성 및 분해

기본 UI는 composedecompose 함수를 사용합니다.

decompose '폭발' 블록을 이동할 수 있는 더 작은 하위 블록으로 만듭니다. 추가, 삭제가 가능합니다. 이 함수는 'top block'을 반환해야 합니다. 즉 하위 블록이 연결되는 뮤테이터 작업공간의 기본 블록입니다.

그러면 compose는 하위 블록의 구성을 해석하고 이를 사용하여 기본 블록을 수정합니다. 이 함수는 'top block'을 허용해야 합니다. 이었습니다 decompose에서 매개변수로 반환합니다.

이러한 함수는 '변경'되는 블록입니다. 그래서 this 해당 블록을 참조하는 데 사용할 수 있습니다.

// These are the decompose and compose functions for the lists_create_with block.
decompose: function(workspace) {
  // This is a special sub-block that only gets created in the mutator UI.
  // It acts as our "top block"
  var topBlock = workspace.newBlock('lists_create_with_container');
  topBlock.initSvg();

  // Then we add one sub-block for each item in the list.
  var connection = topBlock.getInput('STACK').connection;
  for (var i = 0; i < this.itemCount_; i++) {
    var itemBlock = workspace.newBlock('lists_create_with_item');
    itemBlock.initSvg();
    connection.connect(itemBlock.previousConnection);
    connection = itemBlock.nextConnection;
  }

  // And finally we have to return the top-block.
  return topBlock;
},

// The container block is the top-block returned by decompose.
compose: function(topBlock) {
  // First we get the first sub-block (which represents an input on our main block).
  var itemBlock = topBlock.getInputTargetBlock('STACK');

  // Then we collect up all of the connections of on our main block that are
  // referenced by our sub-blocks.
  // This relates to the saveConnections hook (explained below).
  var connections = [];
  while (itemBlock && !itemBlock.isInsertionMarker()) {  // Ignore insertion markers!
    connections.push(itemBlock.valueConnection_);
    itemBlock = itemBlock.nextConnection &&
        itemBlock.nextConnection.targetBlock();
  }

  // Then we disconnect any children where the sub-block associated with that
  // child has been deleted/removed from the stack.
  for (var i = 0; i < this.itemCount_; i++) {
    var connection = this.getInput('ADD' + i).connection.targetConnection;
    if (connection && connections.indexOf(connection) == -1) {
      connection.disconnect();
    }
  }

  // Then we update the shape of our block (removing or adding iputs as necessary).
  // `this` refers to the main block.
  this.itemCount_ = connections.length;
  this.updateShape_();

  // And finally we reconnect any child blocks.
  for (var i = 0; i < this.itemCount_; i++) {
    connections[i].reconnect(this, 'ADD' + i);
  }
},

saveConnections

원하는 경우 다음과 함께 작동하는 saveConnections 함수를 정의할 수도 있습니다. 사용할 수 있습니다. 이 함수를 사용하면 기본 블록 (기본 작업공간에 있음)과 변경할 수 있습니다 그런 다음 이 데이터를 사용하여 compose을(를) 확인할 수 있습니다. 함수는 기본 블록의 하위 요소를 올바르게 다시 하위 블록이 재구성됩니다.

saveConnections는 '상단 블록'을 허용해야 합니다. decompose에서 반환함 함수를 매개변수로 전달합니다. saveConnections 함수가 정의된 경우 Blockly compose를 호출하기 전에 호출합니다.

saveConnections: function(topBlock) {
  // First we get the first sub-block (which represents an input on our main block).
  var itemBlock = topBlock.getInputTargetBlock('STACK');

  // Then we go through and assign references to connections on our main block
  // (input.connection.targetConnection) to properties on our sub blocks
  // (itemBlock.valueConnection_).
  var i = 0;
  while (itemBlock) {
    // `this` refers to the main block (which is being "mutated").
    var input = this.getInput('ADD' + i);
    // This is the important line of this function!
    itemBlock.valueConnection_ = input && input.connection.targetConnection;
    i++;
    itemBlock = itemBlock.nextConnection &&
        itemBlock.nextConnection.targetBlock();
  }
},

등록 중

뮤테이터는 특수한 종류의 확장이므로 블록 유형의 JSON에서 사용할 수 있습니다. 정의를 참조하세요.

// Function signature.
Blockly.Extensions.registerMutator(name, mixinObj, opt_helperFn, opt_blockList);

// Example call.
Blockly.Extensions.registerMutator(
    'controls_if_mutator',
    { /* mutator methods */ },
    undefined,
    ['controls_if_elseif', 'controls_if_else']);
  • name: JSON에서 사용할 수 있도록 변형자와 연결할 문자열입니다.
  • mixinObj: 다양한 변형 메서드를 포함하는 객체입니다. 예: saveExtraStateloadExtraState.
  • opt_helperFn: 선택적 도우미 함수입니다. 믹스인이 믹스인 후 블록에서 실행됩니다.
  • opt_blockList: 블록 유형의 배열(문자열)입니다(선택사항). 기본 뮤테이터 UI의 플라이아웃에 추가됩니다. 정의할 수 있습니다

확장 프로그램과 달리 각 블록 유형에는 하나의 뮤테이터만 있을 수 있습니다.

{
  //...
  "mutator": "controls_if_mutator"
}

도우미 함수

믹스인과 함께 변형자는 도우미 함수를 등록할 수 있습니다. 이 함수는 특정 유형의 각 블록에서 실행되고 믹스inObj는 추가되었습니다. 변형에 추가 트리거 또는 효과를 추가하는 데 사용할 수 있습니다.

예를 들어 초기 품목 수:

var helper = function() {
  this.itemCount_ = 5;
  this.updateShape();
}