새 필드 유형 만들기

새 필드 유형을 만들기 전에 필드를 맞춤설정하는 다른 메서드 중 하나가 필요에 적합한지 고려하세요. 애플리케이션이 새 값 유형을 저장해야 하거나 기존 값 유형을 위한 새 UI를 만들려는 경우에는 새 필드 유형을 만들어야 할 수 있습니다.

새 필드를 만들려면 다음 단계를 따르세요.

  1. 생성자를 구현합니다.
  2. JSON 키를 등록하고 fromJson를 구현합니다.
  3. 온블록 UI 및 이벤트 리스너의 초기화를 처리합니다.
  4. 이벤트 리스너 폐기 처리 (UI 폐기는 자동으로 처리됨).
  5. 값 처리를 구현합니다.
  6. 접근성을 위해 필드 값의 텍스트 표현을 추가합니다.
  7. 다음과 같은 기능을 추가합니다.
  8. 필드에서 다음과 같은 추가 요소를 구성합니다.

이 섹션에서는 사용자가 필드 분석의 내용을 읽고 숙지했다고 가정합니다.

맞춤 필드의 예는 맞춤 필드 데모를 참고하세요.

생성자 구현

필드의 생성자가 필드의 초깃값을 설정하고 선택적으로 로컬 유효성 검사 도구를 설정합니다. 커스텀 필드의 생성자는 소스 블록이 JSON 또는 자바스크립트로 정의되었는지 여부에 관계없이 소스 블록 초기화 중에 호출됩니다. 따라서 맞춤 필드는 생성 중에는 소스 블록에 액세스할 수 없습니다.

다음 코드 샘플은 GenericField라는 커스텀 필드를 만듭니다.

class GenericField extends Blockly.Field {
  constructor(value, validator) {
    super(value, validator);

    this.SERIALIZABLE = true;
  }
}

메서드 서명

필드 생성자는 일반적으로 값과 로컬 검사기를 사용합니다. 이 값은 선택사항이며, 값을 전달하지 않거나 클래스 유효성 검사에 실패한 값을 전달하면 슈퍼클래스의 기본값이 사용됩니다. 기본 Field 클래스의 경우 값은 null입니다. 이러한 기본값을 원하지 않으면 적절한 값을 전달해야 합니다. 검사기 매개변수는 수정 가능한 필드에만 표시되며 일반적으로 선택사항으로 표시됩니다. 유효성 검사 도구 문서에서 검사기에 관해 자세히 알아보세요.

구조

생성자 내부의 로직은 다음 흐름을 따라야 합니다.

  1. 상속된 슈퍼 생성자 (모든 맞춤 필드는 Blockly.Field 또는 서브클래스 중 하나에서 상속되어야 함)를 호출하여 값을 올바르게 초기화하고 필드의 로컬 유효성 검사기를 설정합니다.
  2. 필드가 직렬화될 수 있으면 생성자에서 해당 속성을 설정합니다. 수정 가능한 필드는 직렬화할 수 있어야 하고 필드는 기본적으로 수정 가능하므로 직렬화할 수 없어야 한다는 사실을 모르는 경우 이 속성을 true로 설정해야 합니다.
  3. 선택사항: 추가 맞춤설정을 적용합니다. 예를 들어 라벨 필드를 사용하면 css 클래스를 전달할 수 있으며 이는 텍스트에 적용됩니다.

JSON 및 등록

JSON 블록 정의에서 필드는 문자열 (예: field_number, field_textinput)로 설명됩니다. 이러한 문자열에서 필드 객체로 연결되는 맵을 블록으로 유지하고 생성 중에 적절한 객체에서 fromJson를 호출합니다.

Blockly.fieldRegistry.register를 호출하여 이 맵에 필드 유형을 추가하고 필드 클래스를 두 번째 인수로 전달합니다.

Blockly.fieldRegistry.register('field_generic', GenericField);

fromJson 함수도 정의해야 합니다. 구현 시 먼저 replaceMessageReferences를 사용하여 문자열 테이블 참조를 역참조한 후 해당 값을 생성자에 전달해야 합니다.

GenericField.fromJson = function(options) {
  const value = Blockly.utils.parsing.replaceMessageReferences(
      options['value']);
  return new CustomFields.GenericField(value);
};

초기화 중

필드가 구성되면 기본적으로 값만 포함됩니다. 초기화에서는 DOM이 빌드되고 모델이 빌드되고 (필드에 모델이 있는 경우), 이벤트가 바인딩됩니다.

온블록 디스플레이

초기화 중에 필드의 블록 온 디스플레이에 필요한 모든 것을 만들어야 합니다.

기본값, 배경, 텍스트

기본 initView 함수는 밝은 색상의 rect 요소와 text 요소를 만듭니다. 필드에 이러한 두 가지 기능과 추가 혜택을 모두 적용하려면 슈퍼클래스 initView 함수를 호출한 후 나머지 DOM 요소를 추가합니다. 필드에 이러한 요소 중 하나만 있도록 하려면 createBorderRect_ 또는 createTextElement_ 함수를 사용하면 됩니다.

DOM 생성 맞춤설정

필드가 일반 텍스트 필드 (예: 텍스트 입력)인 경우 DOM 생성이 자동으로 처리됩니다. 그러지 않으면 initView 함수를 재정의하여 향후 필드를 렌더링할 때 필요한 DOM 요소를 만들어야 합니다.

예를 들어 드롭다운 필드에 이미지와 텍스트가 모두 포함될 수 있습니다. initView에서는 단일 이미지 요소와 단일 텍스트 요소를 생성합니다. 그런 다음 render_ 중에 선택한 옵션의 유형에 따라 활성 요소를 표시하고 다른 요소는 숨깁니다.

DOM 요소는 Blockly.utils.dom.createSvgElement 메서드를 사용하거나 기존 DOM 만들기 메서드를 사용하여 만들 수 있습니다.

필드의 블록 내 디스플레이 요구사항은 다음과 같습니다.

  • 모든 DOM 요소는 필드 fieldGroup_의 하위 요소여야 합니다. 필드 그룹이 자동으로 생성됩니다.
  • 모든 DOM 요소는 보고된 필드 크기 내에 있어야 합니다.

온블록 디스플레이를 맞춤설정하고 업데이트하는 방법에 관한 자세한 내용은 렌더링 섹션을 참고하세요.

텍스트 기호 추가

필드의 텍스트(예: Angle 필드의 도 기호)에 기호를 추가하려면 일반적으로 <tspan>에 포함되는 기호 요소를 필드의 textElement_에 직접 추가하면 됩니다.

입력 이벤트

기본적으로 필드는 도움말 이벤트, mousedown 이벤트 (편집기를 표시하는 데 사용됨)를 등록합니다. 다른 종류의 이벤트를 수신 대기하려면 (예: 필드 드래그를 처리하려는 경우) 필드의 bindEvents_ 함수를 재정의해야 합니다.

bindEvents_() {
  // Call the superclass function to preserve the default behavior as well.
  super.bindEvents_();

  // Then register your own additional event listeners.
  this.mouseDownWrapper_ =
  Blockly.browserEvents.conditionalBind(this.getClickTarget_(), 'mousedown', this,
      function(event) {
        this.originalMouseX_ = event.clientX;
        this.isMouseDown_ = true;
        this.originalValue_ = this.getValue();
        event.stopPropagation();
      }
  );
  this.mouseMoveWrapper_ =
    Blockly.browserEvents.conditionalBind(document, 'mousemove', this,
      function(event) {
        if (!this.isMouseDown_) {
          return;
        }
        var delta = event.clientX - this.originalMouseX_;
        this.setValue(this.originalValue_ + delta);
      }
  );
  this.mouseUpWrapper_ =
    Blockly.browserEvents.conditionalBind(document, 'mouseup', this,
      function(_event) {
        this.isMouseDown_ = false;
      }
  );
}

이벤트에 결합하려면 일반적으로 Blockly.utils.browserEvents.conditionalBind 함수를 사용해야 합니다. 이 결합 이벤트 방법은 드래그 중에 보조 터치를 필터링합니다. 드래그가 진행 중인 도중에도 핸들러를 실행하려면 Blockly.browserEvents.bind 함수를 사용하면 됩니다.

폐기 중

필드의 bindEvents_ 함수 내에 맞춤 이벤트 리스너를 등록한 경우 dispose 함수 내에서 맞춤 이벤트 리스너를 등록 취소해야 합니다.

모든 DOM 요소를 fieldGroup_에 추가하여 필드의 뷰를 올바르게 초기화하면 필드의 DOM이 자동으로 삭제됩니다.

값 처리

→ 필드의 값과 텍스트를 비교한 내용을 자세히 알아보려면 필드 분석을 참고하세요.

검증 순서

검사기가 실행되는 순서를 설명하는 플로우 차트

클래스 검사기 구현

필드는 특정 값만 허용해야 합니다. 예를 들어 숫자 필드는 숫자만 허용해야 하며 색상 필드는 색상만 허용해야 합니다. 이는 클래스 및 로컬 검사기를 통해 확인할 수 있습니다. 클래스 검사기는 로컬 검사기와 동일한 규칙을 따릅니다. 단, 생성자에서도 실행되므로 소스 블록을 참조해서는 안 됩니다.

필드의 클래스 검사기를 구현하려면 doClassValidation_ 함수를 재정의합니다.

doClassValidation_(newValue) {
  if (typeof newValue != 'string') {
    return null;
  }
  return newValue;
};

유효한 값 처리

setValue를 사용하여 필드에 전달된 값이 유효하면 doValueUpdate_ 콜백을 수신하게 됩니다. 기본적으로 doValueUpdate_ 함수는 다음과 같습니다.

  • value_ 속성을 newValue로 설정합니다.
  • isDirty_ 속성을 true로 설정합니다.

값을 저장하고 맞춤 처리를 원하지 않는 경우 doValueUpdate_를 재정의하지 않아도 됩니다.

그렇지 않은 경우 다음과 같은 작업을 할 수 있습니다.

  • newValue의 맞춤 스토리지
  • newValue에 따라 다른 속성을 변경합니다.
  • 현재 값이 유효한지 여부를 저장합니다.

doValueUpdate_를 재정의해야 합니다.

doValueUpdate_(newValue) {
  super.doValueUpdate_(newValue);
  this.displayValue_ = newValue;
  this.isValueValid_ = true;
}

잘못된 값 처리

setValue가 있는 필드에 전달된 값이 유효하지 않으면 doValueInvalid_ 콜백이 수신됩니다. 기본적으로 doValueInvalid_ 함수는 아무 작업도 하지 않습니다. 즉, 기본적으로 잘못된 값은 표시되지 않습니다. 또한 isDirty_ 속성이 설정되지 않으므로 필드가 다시 렌더링되지 않습니다.

잘못된 값을 표시하려면 doValueInvalid_를 재정의해야 합니다. 대부분의 경우 displayValue_ 속성을 잘못된 값으로 설정하고, isDirty_true로 설정하고, 블록 내 디스플레이가 value_ 대신 displayValue_에 따라 업데이트되도록 렌더링을 재정의해야 합니다.

doValueInvalid_(newValue) {
  this.displayValue_ = newValue;
  this.isDirty_ = true;
  this.isValueValid_ = false;
}

여러 부분으로 된 값

필드에 멀티파트 값 (예: 목록, 벡터, 객체)이 포함된 경우 파트를 개별 값처럼 처리할 수 있습니다.

doClassValidation_(newValue) {
  if (FieldTurtle.PATTERNS.indexOf(newValue.pattern) == -1) {
    newValue.pattern = null;
  }

  if (FieldTurtle.HATS.indexOf(newValue.hat) == -1) {
    newValue.hat = null;
  }

  if (FieldTurtle.NAMES.indexOf(newValue.turtleName) == -1) {
    newValue.turtleName = null;
  }

  if (!newValue.pattern || !newValue.hat || !newValue.turtleName) {
    this.cachedValidatedValue_ = newValue;
    return null;
  }
  return newValue;
}

위 예에서 newValue의 각 속성은 개별적으로 검증됩니다. 그런 다음 doClassValidation_ 함수의 끝에서 개별 속성이 유효하지 않으면 null (유효하지 않음)를 반환하기 전에 값이 cacheValidatedValue_ 속성에 캐시됩니다. 개별적으로 검증된 속성으로 객체를 캐싱하면 doValueInvalid_ 함수가 각 속성을 개별적으로 다시 검증하는 대신 !this.cacheValidatedValue_.property 검사를 실행하여 객체를 개별적으로 처리할 수 있습니다.

다중 파트 값의 유효성을 검사하는 이 패턴을 로컬 유효성 검사 도구에도 사용할 수 있지만 현재는 이 패턴을 적용할 방법이 없습니다.

isDirty_

isDirty_는 필드를 다시 렌더링해야 하는지 알리기 위해 필드의 다른 부분뿐만 아니라 setValue 함수에서도 사용되는 플래그입니다. 필드의 표시 값이 변경된 경우 일반적으로 isDirty_true로 설정해야 합니다.

텍스트

→ 필드의 텍스트가 사용되는 위치 및 필드의 값과의 차이점에 대한 자세한 내용은 필드 분석을 참조하세요.

필드의 텍스트가 필드의 값과 다른 경우 올바른 텍스트를 제공하도록 getText 함수를 재정의해야 합니다.

getText() {
  let text = this.value_.turtleName + ' wearing a ' + this.value_.hat;
  if (this.value_.hat == 'Stovepipe' || this.value_.hat == 'Propeller') {
    text += ' hat';
  }
  return text;
}

편집기 만들기

showEditor_ 함수를 정의하면 Blockly가 자동으로 클릭을 수신 대기하고 적절한 시점에 showEditor_를 호출합니다. Blockly UI의 나머지 부분 위에 플로팅되는 DropDownDiv 및 WidgetDiv라는 두 개의 특수 div 중 하나로 래핑하여 편집기에 HTML을 표시할 수 있습니다.

DropDownDiv는 필드에 연결된 상자 안에 있는 편집기를 제공하는 데 사용됩니다. 표시된 경계 내에 있으면서 필드 근처에 있도록 자동으로 배치됩니다. 각도 선택 도구와 색상 선택 도구는 DropDownDiv의 좋은 예입니다.

각도 선택 도구 이미지

WidgetDiv는 상자 안에 있지 않는 편집자를 제공하는 데 사용됩니다. 숫자 필드는 WidgetDiv를 사용하여 HTML 텍스트 입력 상자로 필드를 덮습니다. DropDownDiv는 배치를 처리하지만 WidgetDiv는 그렇지 않습니다. 요소는 수동으로 배치해야 합니다. 좌표계는 창의 왼쪽 상단을 기준으로 한 픽셀 좌표입니다. 텍스트 입력 편집기는 WidgetDiv의 좋은 예입니다.

텍스트 입력 편집기 이미지

showEditor_() {
  // Create the widget HTML
  this.editor_ = this.dropdownCreate_();
  Blockly.DropDownDiv.getContentDiv().appendChild(this.editor_);

  // Set the dropdown's background colour.
  // This can be used to make it match the colour of the field.
  Blockly.DropDownDiv.setColour('white', 'silver');

  // Show it next to the field. Always pass a dispose function.
  Blockly.DropDownDiv.showPositionedByField(
      this, this.disposeWidget_.bind(this));
}

WidgetDiv 샘플 코드

showEditor_() {
  // Show the div. This automatically closes the dropdown if it is open.
  // Always pass a dispose function.
  Blockly.WidgetDiv.show(
    this, this.sourceBlock_.RTL, this.widgetDispose_.bind(this));

  // Create the widget HTML.
  var widget = this.createWidget_();
  Blockly.WidgetDiv.getDiv().appendChild(widget);
}

삭제

DropDownDiv와 WidgetDiv 모두 위젯 HTML 요소를 폐기하지만 이러한 요소에 적용한 이벤트 리스너를 수동으로 폐기해야 합니다.

widgetDispose_() {
  for (let i = this.editorListeners_.length, listener;
      listener = this.editorListeners_[i]; i--) {
    Blockly.browserEvents.unbind(listener);
    this.editorListeners_.pop();
  }
}

dispose 함수는 DropDownDivnull 컨텍스트에서 호출됩니다. WidgetDiv에서는 WidgetDiv 컨텍스트에서 호출됩니다. 두 경우 모두 위의 DropDownDivWidgetDiv 예와 같이 삭제 함수를 전달할 때 bind 함수를 사용하는 것이 가장 좋습니다.

→ 편집자 폐기와 관련 없는 폐기에 관한 자세한 내용은 삭제를 참고하세요.

블록 내 디스플레이 업데이트

render_ 함수는 필드의 블록 내 디스플레이를 내부 값과 일치하도록 업데이트하는 데 사용됩니다.

일반적인 예는 다음과 같습니다.

  • 텍스트 변경 (드롭다운)
  • 색상 (색상)을 변경합니다.

기본값

기본 render_ 함수는 표시 텍스트를 getDisplayText_ 함수의 결과로 설정합니다. getDisplayText_ 함수는 최대 텍스트 길이를 반영하도록 필드가 잘린 후 문자열로 변환된 필드의 value_ 속성을 반환합니다.

기본 온블록 디스플레이를 사용하고 기본 텍스트 동작이 필드에서 작동하는 경우 render_를 재정의할 필요가 없습니다.

필드에서 기본 텍스트 동작이 작동하지만 필드의 블록 내 디스플레이에 추가 정적 요소가 있는 경우 기본 render_ 함수를 호출할 수 있지만 여전히 이 함수를 재정의하여 필드 크기를 업데이트해야 합니다.

필드에 기본 텍스트 동작이 작동하지 않거나 필드의 블록 디스플레이에 추가 동적 요소가 있는 경우 render_ 함수를 맞춤설정해야 합니다.

렌더링 재정의 여부를 결정하는 방법을 설명하는 플로우 차트

렌더링 맞춤설정

기본 렌더링 동작이 필드에 적합하지 않으면 맞춤 렌더링 동작을 정의해야 합니다. 여기에는 맞춤 디스플레이 텍스트 설정, 이미지 요소 변경, 배경 색상 업데이트에 이르기까지 모든 작업이 포함될 수 있습니다.

모든 DOM 속성 변경은 합법적이며 기억해야 할 두 가지는 다음과 같습니다.

  1. DOM 생성초기화 중에 처리해야 하는데 이렇게 하는 것이 더 효율적입니다.
  2. 개발자는 항상 블록 내 디스플레이의 크기와 일치하도록 size_ 속성을 업데이트해야 합니다.
render_() {
  switch(this.value_.hat) {
    case 'Stovepipe':
      this.stovepipe_.style.display = '';
      break;
    case 'Crown':
      this.crown_.style.display = '';
      break;
    case 'Mask':
      this.mask_.style.display = '';
      break;
    case 'Propeller':
      this.propeller_.style.display = '';
      break;
    case 'Fedora':
      this.fedora_.style.display = '';
      break;
  }

  switch(this.value_.pattern) {
    case 'Dots':
      this.shellPattern_.setAttribute('fill', 'url(#polkadots)');
      break;
    case 'Stripes':
      this.shellPattern_.setAttribute('fill', 'url(#stripes)');
      break;
    case 'Hexagons':
      this.shellPattern_.setAttribute('fill', 'url(#hexagons)');
      break;
  }

  this.textContent_.nodeValue = this.value_.turtleName;

  this.updateSize_();
}

크기 업데이트 중

필드의 size_ 속성을 업데이트하는 것은 블록 렌더링 코드에 필드를 배치하는 방법을 알려주므로 매우 중요합니다. size_가 정확히 무엇인지 정확히 파악하는 가장 좋은 방법은 실험하는 것입니다.

updateSize_() {
  const bbox = this.movableGroup_.getBBox();
  let width = bbox.width;
  let height = bbox.height;
  if (this.borderRect_) {
    width += this.constants_.FIELD_BORDER_RECT_X_PADDING * 2;
    height += this.constants_.FIELD_BORDER_RECT_X_PADDING * 2;
    this.borderRect_.setAttribute('width', width);
    this.borderRect_.setAttribute('height', height);
  }
  // Note how both the width and the height can be dynamic.
  this.size_.width = width;
  this.size_.height = height;
}

블록 색상 일치

필드의 요소를 요소가 연결된 블록의 색상과 일치시키려면 applyColour 메서드를 재정의해야 합니다. 블록의 style 속성을 통해 색상에 액세스하는 것이 좋습니다.

applyColour() {
  const sourceBlock = this.sourceBlock_;
  if (sourceBlock.isShadow()) {
    this.arrow_.style.fill = sourceBlock.style.colourSecondary;
  } else {
    this.arrow_.style.fill = sourceBlock.style.colourPrimary;
  }
}

수정 가능 여부 업데이트 중

updateEditable 함수를 사용하면 수정 가능 여부에 따라 필드가 표시되는 방식을 변경할 수 있습니다. 기본 함수는 배경이 수정 가능하거나 불가능한 경우 배경에 마우스 오버 응답 (테두리)을 포함하거나 포함하지 않도록 합니다. 온블록 디스플레이는 편집 가능성에 따라 크기가 변경되지 않아야 하지만 다른 모든 변경은 허용됩니다.

updateEditable() {
  if (!this.fieldGroup_) {
    // Not initialized yet.
    return;
  }
  super.updateEditable();

  const group = this.getClickTarget_();
  if (!this.isCurrentlyEditable()) {
    group.style.cursor = 'not-allowed';
  } else {
    group.style.cursor = this.CURSOR;
  }
}

직렬화

직렬화는 나중에 작업공간으로 다시 로드할 수 있도록 필드의 상태를 저장하는 것입니다.

작업공간의 상태에는 항상 필드 값이 포함되지만, 필드 UI 상태와 같은 다른 상태도 포함될 수 있습니다. 예를 들어 필드가 사용자가 국가를 선택할 수 있는 확대/축소 가능한 지도인 경우 확대/축소 수준을 직렬화할 수도 있습니다.

필드를 직렬화할 수 있으면 SERIALIZABLE 속성을 true로 설정해야 합니다.

Blockly는 필드에 두 가지 직렬화 후크 세트를 제공합니다. 한 쌍의 후크는 새로운 JSON 직렬화 시스템에서 작동하며, 다른 쌍은 이전 XML 직렬화 시스템에서 작동합니다.

saveStateloadState

saveStateloadState는 새 JSON 직렬화 시스템에서 작동하는 직렬화 후크입니다.

경우에 따라서는 기본 구현이 작동하므로 이를 제공할 필요가 없습니다. (1) 필드가 기본 Blockly.Field 클래스의 직접적인 서브클래스이고, (2) 값이 JSON 직렬화 가능 유형이고, (3) 값을 직렬화하기만 하면 되는 경우 기본 구현이 문제없이 작동합니다.

그렇지 않으면 saveState 함수는 필드 상태를 나타내는 JSON 직렬화 가능한 객체/값을 반환해야 합니다. 또한 loadState 함수는 JSON 직렬화 가능한 동일한 객체/값을 허용하고 필드에 적용해야 합니다.

saveState() {
  return {
    'country': this.getValue(),  // Value state
    'zoom': this.getZoomLevel(), // UI state
  };
}

loadState(state) {
  this.setValue(state['country']);
  this.setZoomLevel(state['zoom']);
}

전체 직렬화 및 지원 데이터

saveState는 선택적 매개변수 doFullSerialization도 수신합니다. 이는 일반적으로 다른 직렬 변환기로 직렬화된 상태를 참조하는 필드 (예: 지원 데이터 모델)에 의해 사용됩니다. 매개변수는 블록이 역직렬화될 때 참조된 상태를 사용할 수 없다는 신호를 보내므로 필드가 모든 직렬화를 직접 실행해야 합니다. 예를 들어 개별 블록이 직렬화되거나 블록을 복사하여 붙여넣기할 때 마찬가지입니다.

이러한 연결의 일반적인 두 가지 사용 사례는 다음과 같습니다.

  • 지원 데이터 모델이 없는 작업공간에 개별 블록이 로드되면 필드에 새 데이터 모델을 만들기에 충분한 자체 상태의 정보가 있습니다.
  • 블록을 복사하여 붙여넣으면 필드는 기존 지원 데이터 모델을 참조하는 대신 항상 새로운 지원 데이터 모델을 만듭니다.

이를 사용하는 필드 중 하나가 기본 제공 변수 필드입니다. 일반적으로 참조하는 변수의 ID를 직렬화하지만 doFullSerialization이 true이면 모든 상태를 직렬화합니다.

saveState(doFullSerialization) {
  const state = {'id': this.variable_.getId()};
  if (doFullSerialization) {
    state['name'] = this.variable_.name;
    state['type'] = this.variable_.type;
  }
  return state;
}

loadState(state) {
  const variable = Blockly.Variables.getOrCreateVariablePackage(
      this.getSourceBlock().workspace,
      state['id'],
      state['name'],   // May not exist.
      state['type']);  // May not exist.
  this.setValue(variable.getId());
}

변수 필드는 변수가 없는 작업공간에 로드되는 경우 참조할 새 변수를 만들 수 있도록 합니다.

toXmlfromXml

toXmlfromXml는 이전 XML 직렬화 시스템에서 작동하는 직렬화 후크입니다. 이러한 후크는 필요한 경우에만 사용하고 (예: 아직 이전하지 않은 이전 코드베이스를 사용하는 경우) saveStateloadState을 사용하세요.

toXml 함수는 필드 상태를 나타내는 XML 노드를 반환해야 합니다. 또한 fromXml 함수는 동일한 XML 노드를 받아서 필드에 적용해야 합니다.

toXml(fieldElement) {
  fieldElement.textContent = this.getValue();
  fieldElement.setAttribute('zoom', this.getZoomLevel());
  return fieldElement;
}

fromXml(fieldElement) {
  this.setValue(fieldElement.textContent);
  this.setZoomLevel(fieldElement.getAttribute('zoom'));
}

수정 가능한 속성 및 직렬화 가능한 속성

EDITABLE 속성은 필드에 상호작용할 수 있음을 나타내는 UI가 있어야 하는지 결정합니다. 기본값은 true입니다.

SERIALIZABLE 속성은 필드를 직렬화해야 하는지 여부를 결정합니다. 기본값은 false입니다. 이 속성이 true인 경우 직렬화 및 역직렬화 함수를 제공해야 할 수도 있습니다 (직렬화 참고).

커서 맞춤설정

CURSOR 속성은 사용자가 필드 위로 마우스를 가져가면 표시되는 커서를 결정합니다. 유효한 CSS 커서 문자열이어야 합니다. 기본적으로 .blocklyDraggable에 의해 정의된 커서(그랩 커서)로 지정됩니다.