新しいフィールド タイプを作成する前に、もう一方のタイプを メソッド カスタマイズする方法もいくつかあります。アプリケーションで 既存の値の型に新しい UI を作成する場合は、 新しいフィールド タイプの作成が必要になる可能性があります。
新しいフィールドを作成する手順は次のとおりです。
- コンストラクタを実装する。
- JSON キーを登録して
fromJson
を実装します。 - ブロック上の UI とイベントの初期化を処理する 使用できます。
- イベント リスナーの破棄を処理(UI の破棄は ユーザー)。
- 値の処理を実装する。
- ユーザー補助のために、フィールドの値のテキスト表現を追加する。
- 次のような機能を追加します。
<ph type="x-smartling-placeholder">
- </ph>
- 編集者。
- オンブロック ディスプレイの更新。
- シリアル化。
- 次のようなフィールドの追加要素を設定します。
<ph type="x-smartling-placeholder">
- </ph>
- 編集とシリアル化が可能 プロパティ
- Cursor
このセクションは、 フィールド。
カスタム フィールドの例については、カスタム フィールド デモ をタップします。
コンストラクタの実装
フィールドのコンストラクタは、フィールドの初期値を設定する役割を担います。 必要に応じて、ローカル バリデータ。カスタム フィールドのコンストラクタが呼び出されるのは、 ソースブロックが JSON と JavaScript のどちらで定義されているかを示す指標です。したがって、カスタム フィールドには、作成時にソースブロックへのアクセス権がありません。
次のコードサンプルでは、GenericField
という名前のカスタム フィールドを作成します。
class GenericField extends Blockly.Field {
constructor(value, validator) {
super(value, validator);
this.SERIALIZABLE = true;
}
}
メソッドのシグネチャ
フィールド コンストラクタは通常、値とローカル バリデータを受け取ります。値は
オプションです。また、値を渡さない場合(または、class に失敗する値を
スーパークラスのデフォルト値が使用されます。対象:
デフォルトの Field
クラスの場合、値は null
です。このデフォルトを使用しない場合は、
適切な値を渡すようにしてください。Validator パラメータは
編集可能なフィールドでは存在し、通常はオプションとしてマークされます。詳細
詳しくは、Validators、
ドキュメントをご覧ください。
構造
コンストラクタ内のロジックは、次のフローに従う必要があります。
- 継承されたスーパー コンストラクタを呼び出す(すべてのカスタム フィールドは
Blockly.Field
またはそのサブクラスのいずれか)を使用して、値を適切に初期化します。 フィールドにローカル検証ツールを設定します。 - フィールドがシリアル化可能である場合は、 コンストラクタがあります。編集可能なフィールドはシリアル化可能でなければならず、編集可能である必要がある ですからこのプロパティを true に設定することをおすすめします。 シリアル化可能であってはなりません。
- 省略可: 追加のカスタマイズを適用する(ラベルのフィールドなど) CSS クラスを渡し、それがテキストに適用されます)。
JSON と登録
JSON ブロック内
定義
フィールドは文字列(例: field_number
、field_textinput
)で記述します。
Blockly は、これらの文字列からフィールド オブジェクトへのマップを維持し、
作成中に適切なオブジェクトに対する fromJson
。
Blockly.fieldRegistry.register
を呼び出して、このマップにフィールド タイプを追加します。
2 番目の引数としてフィールド クラスを渡します。
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 構築のカスタマイズ
フィールドが汎用テキスト フィールド(例: Text
Input)、
DOM 構築は自動的に行われます。それ以外の場合は、値をオーバーライドする必要があります。
initView
関数を使用して、必要な DOM 要素を作成する
詳しく見ていきます。
たとえば、プルダウン フィールドには画像とテキストの両方を含めることができます。initView
で
は、1 つの画像要素と 1 つのテキスト要素を作成します。その後、render_
の期間中
アクティブな要素を表示し、もう一方を非表示にします。元の要素は、
選択します。
DOM 要素の作成は、
Blockly.utils.dom.createSvgElement
メソッド、または従来の DOM 作成
あります。
フィールドのオンブロック表示の要件は次のとおりです。
- すべての DOM 要素はフィールドの
fieldGroup_
の子である必要があります。フィールド グループが自動的に作成されます。 - すべての DOM 要素は、フィールドについてレポートされるディメンションの範囲内に収まる必要があります。
詳しくは、 レンダリング をご覧ください。
テキスト記号の追加
フィールドのテキストに記号(
角度
次フィールドの次数記号など)を使用する場合は、記号要素(通常は
<tspan>
など)をフィールドの textElement_
に直接渡すこともできます。
入力イベント
デフォルトでは、各フィールドはツールチップ イベントとマウスダウン イベント(
表示中
編集者など)。
他の種類のイベントをリッスンしたい場合(例:
フィールドのドラッグなど)を行う場合は、そのフィールドの 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 は自動的に破棄されます。
価値の処理
→ フィールドの値とテキストの詳細については、フィールドの構造 フィールド。
検証順序
クラス バリデータの実装
フィールドには特定の値のみを指定できます。たとえば数値フィールドでは 色フィールドには色などしか入力できません 地域社会で バリデータ。クラス ローカル バリデータと同じルールに従うが、ローカル バリデータも実行される の コンストラクタ source ブロックを参照しないようにする必要があります。
フィールドのクラス バリデータを実装するには、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
に設定して、オーバーライドする
render_
オンブロック ディスプレイを、displayValue_
に基づいて
value_
。
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_
関数の最後にあります(個々のプロパティがある場合、
無効の場合、値はcacheValidatedValue_
null
を返します(無効)。個別に検証されたオブジェクトをキャッシュに保存する
プロパティを使用すると、
doValueInvalid_
関数を使用して個別に処理します。これは、
各データを再検証する代わりに、!this.cacheValidatedValue_.property
チェックを
プロパティを個別に設定します。
マルチパート値を検証するこのパターンは、ローカル バリデータですが、 現在のところ、このパターンを適用する方法はありません。
isDirty_
isDirty_
は、Pod で使用するフラグです。
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_
を呼び出します。任意の HTML を表示可能
エディタで DropDownDiv という 2 つの特別な div のいずれかでラップして、
そして WidgetDiv はブロックリーの UI の上にフロート表示されます。
DropDownDiv と WidgetDiv
DropDownDiv
は、接続されたボックス内にあるエディタを提供するために使用されます。
マッピングできます。自動的にフィールドの近くに来るように位置します
移動しますアングルピッカーやカラーピッカーは、
DropDownDiv
。
WidgetDiv
は、以下の目的に使用されます。
エディタはボックス内には収まらない。数値フィールドでは
HTML テキスト入力ボックスでフィールドを覆う WidgetDiv。DropDownDiv は
自動的に配置が処理されますが、WidgetDiv は処理しません。要素は次の条件を満たしている必要があります。
手動で配置します。座標系は、座標を基準とするピクセル座標です。
アクセスできます。テキスト入力エディタは
WidgetDiv
。
DropDownDiv のサンプルコード
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
関数は、DropDownDiv
の null
コンテキストで呼び出されます。オン
WidgetDiv
のコンテキストで呼び出されます。WidgetDiv
いずれの場合も
前のスライドの
bind
上記の DropDownDiv
に示すように、dispose 関数を渡すときにその関数を渡します。
と WidgetDiv
の例。
→ 編集者の破棄に限らず、破棄については、以下をご覧ください。 破棄。
オンブロック ディスプレイの更新
render_
関数を使用して、フィールドのオンブロック ディスプレイを
その内部値で識別されます。
一般的な例:
- テキスト(プルダウン)を変更する
- 色(色)を変更する
デフォルト
デフォルトの render_
関数は、表示テキストを
getDisplayText_
使用します。getDisplayText_
関数は、フィールドの value_
プロパティを返します。
最大テキストに合わせて切り捨てられた後の文字列にキャストする
あります。
デフォルトのブロック中表示とデフォルトのテキスト動作を使用している場合
適切に動作するため、render_
をオーバーライドする必要はありません。
デフォルトのテキスト動作がフィールドで機能しても、フィールドがオンブロックである場合
ディスプレイに追加の静的要素がある場合は、デフォルトの render_
ただし、このフィールドを更新するために、
あります。
デフォルトのテキスト動作がフィールドで動作しない場合や、
オンブロック ディスプレイに追加の動的要素があるため、カスタマイズ
render_
関数です。
レンダリングのカスタマイズ
デフォルトのレンダリング動作がフィールドで動作しない場合は、 カスタム レンダリングの動作を定義します。これにはカスタム設定や テキストの表示 画像要素の変更 背景色の更新など
DOM 属性の変更はすべて法的に認められています。覚えておくべきことは次の 2 点だけです。
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 には、フィールドのシリアル化フックのセットが 2 つあります。1 組のフック 他のペアは新しい JSON シリアル化システムで動作し、もう 1 つのペアは 古い XML シリアル化システムです。
saveState
、loadState
saveState
と loadState
: 新しい JSON で動作するシリアル化フック
使用します。
デフォルトのロールはデフォルトのため、
確認しましょう。(1)フィールドが base の直接サブクラスの場合
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
も受け取ります。これは、
別の UDM イベントでシリアル化された状態を通常参照するフィールドで使用されます。
serializer(バッキング データモデルなど)を使用します。このパラメータは
ブロックがシリアル化解除されたときに参照状態を利用できないため、
フィールドがすべてのシリアル化を行います。たとえばこれは
ブロックをシリアライズするかブロックをコピーして貼り付けると、
一般的なユースケースは次の 2 つです。
- バッキングデータが保存されるワークスペースに個々のブロックが モデルが存在しない場合、そのフィールドには、その状態を維持するのに十分な情報が 新しいデータモデルを作成します
- ブロックをコピーして貼り付けると、フィールドによって常に新しいバッキングが作成される データモデルを使用します。
これを使用するフィールドの一つが、組み込み変数フィールドです。通常は
参照している変数の 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());
}
変数フィールドは、ワークスペースに読み込まれたときに 変数が存在しない場合は、参照する新しい変数を作成できます。
toXml
、fromXml
toXml
と fromXml
: 古い XML で動作するシリアル化フック
使用します。これらのフックは必要な場合にのみ使用してください(例:
まだ移行されていない古いコードベースにインストールする)では、saveState
を使用します。
loadState
。
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
(グラブカーソル)で定義されます。