قبل إنشاء نوع حقل جديد، ضع في اعتبارك ما إذا كانت إحدى الطرق الأخرى لتخصيص الحقول تناسب احتياجاتك. إذا كان تطبيقك يحتاج إلى تخزين نوع قيمة جديد، أو كنت تريد إنشاء واجهة مستخدم جديدة لنوع قيمة حالي، قد تحتاج إلى إنشاء نوع حقل جديد.
لإنشاء حقل جديد، يُرجى اتّباع الخطوات التالية:
- تنفيذ دالة إنشائية.
- سجِّل مفتاح JSON ونفِّذ
fromJson
. - التعامل مع إعداد واجهة المستخدم المضمّنة في الحظر والمُستمعون إلى الأحداث:
- التعامل مع أدوات معالجة الأحداث (يتم التعامل مع التخلص من واجهة المستخدم من أجلك)
- تنفيذ معالجة القيمة:
- أضِف تمثيلاً نصيًا لقيمة الحقل لتسهيل الاستخدام.
- يمكنك إضافة وظائف أخرى، مثل:
- اضبط جوانب إضافية للحقل، مثل:
يفترض هذا القسم أنك قد قرأت محتوى تحليل أحد الحقول، وأنك على دراية به.
للحصول على مثال لحقل مخصّص، اطّلِع على العرض التوضيحي للحقول المخصّصة .
تنفيذ دالة إنشائية
تكون الدالة الإنشائية للحقل مسؤولة عن إعداد القيمة الأولية للحقل وإعداد أداة تحقّق محلية اختياريًا. ويتم استدعاء الدالة الإنشائية للحقل المخصّص أثناء إعداد كتلة المصدر بغض النظر عمّا إذا كان قد تم تحديد كتلة المصدر بتنسيق JSON أو JavaScript. لذلك، لا يمكن للحقل المخصص الوصول إلى كتلة المصدر أثناء البناء.
يعمل نموذج الرمز البرمجي التالي على إنشاء حقل مخصّص باسم GenericField
:
class GenericField extends Blockly.Field {
constructor(value, validator) {
super(value, validator);
this.SERIALIZABLE = true;
}
}
توقيع الطريقة
عادةً ما تستخدم منصات إنشاء الحقل قيمة ومدققًا محليًا. تكون القيمة اختيارية، وإذا لم تمرر قيمة (أو مررت قيمة لم تنجح في التحقق من الفئة)، فسيتم استخدام القيمة الافتراضية للفئة الفائقة. بالنسبة إلى
فئة Field
التلقائية، تكون هذه القيمة هي null
. إذا كنت لا تريد هذه القيمة
الافتراضية، فتأكد من تمرير قيمة مناسبة. تتوفّر معلمة أداة التحقق من الصحة فقط للحقول القابلة للتعديل وعادةً ما تحمل علامة اختيارية. تعرَّف على مزيد من المعلومات
حول أدوات التحقق في مستندات
أدوات التحقق من الصحة.
البنية
يجب أن يتبع المنطق داخل الدالة الإنشائية هذا التدفق:
- استدعِ دالة الإنشاء الفائقة الموروثة (يجب أن تكتسب جميع الحقول المخصّصة من
Blockly.Field
أو إحدى فئاتها الفرعية) لضبط القيمة بشكلٍ صحيح وضبط أداة التحقّق المحلية للحقل. - إذا كان الحقل قابلاً للتسلسل، فقم بتعيين الخاصية المقابلة في الدالة الإنشائية. يجب أن تكون الحقول القابلة للتعديل قابلة للتسلسل، والحقول قابلة للتعديل بشكل تلقائي، لذا يجب ضبط هذه الخاصية على "صحيح" إلا إذا كنت تعرف أنّها غير قابلة للتسلسل.
- اختياري: طبِّق تخصيصًا إضافيًا (على سبيل المثال، تسمح حقول التصنيف بتمرير فئة css، والتي يتمّ تطبيقها بعد ذلك على النص).
JSON والتسجيل
في تعريفات مجموعات JSON، يتم وصف الحقول بسلسلة (مثل field_number
وfield_textinput
).
يحتفظ بشكل حظر بخريطة من هذه السلاسل لكائنات الحقول ويستدعي fromJson
للكائن المناسب أثناء الإنشاء.
استدعِ Blockly.fieldRegistry.register
لإضافة نوع الحقل إلى هذه الخريطة، مع تمرير فئة الحقل كوسيطة ثانية:
Blockly.fieldRegistry.register('field_generic', GenericField);
يجب أيضًا تعريف الدالة fromJson
. يجب أن تشير عملية التنفيذ أولاً إلى أي مراجع string
table
باستخدام
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 داخل أبعاد الحقل التي تم الإبلاغ عنها.
راجع قسم العرض للحصول على مزيد من التفاصيل حول تخصيص وتعديل العرض في الحظر.
إضافة رموز نصية
إذا أردت إضافة رموز إلى نص حقل (مثل رمز درجة الزاوية)، يمكنك إلحاق عنصر الرمز (عادةً ما يكون في <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) للحقل تلقائيًا.
التعامل مع القيمة
← للحصول على معلومات حول قيمة الحقل مقارنةً بنصه، راجع بنية الحقل.
طلب التحقق من الصحة
تنفيذ مدقّق الفئة
يجب أن تقبل الحقول قيمًا معيّنة فقط. على سبيل المثال، يجب أن تقبل حقول الأرقام الأرقام فقط، ويجب أن تقبل حقول الألوان الألوان فقط وما إلى ذلك، ويتم ضمان ذلك من خلال الصفوف وأدوات التحقق المحلية. تتّبع أداة التحقق من الفئة القواعد نفسها المتّبعة في أدوات التحقق المحلية، باستثناء أنه يتم تشغيلها أيضًا في أداة الإنشاء، وبالتالي يجب ألا تشير إلى مجموعة المصدر.
لتنفيذ أداة التحقق من الفئة في حقلك، عليك إلغاء
الدالة 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
وإلغاء
العرض_
لكي يتم تعديل العرض ضمن الحظر استنادًا إلى السمة 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_
هي علامة تستخدم في دالة
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_
، سيستمع بشكل تلقائي حظر الإعلانات إلى
النقرات واستدعاء showEditor_
في الوقت المناسب. يمكنك عرض أي ترميز HTML في المحرر من خلال إحاطته بأحد عنصري div الخاصين، يطلق عليهما DropDownDiv وWidgetDiv، واللذين يطفوان فوق بقية واجهة مستخدم Bluely.
DropDownDiv مقابل WidgetDiv
يتم استخدام DropDownDiv
لتوفير المحررين الذين يتواجدون داخل مربع متصل
بحقل. يقوم تلقائيًا بوضع نفسه ليكون بالقرب من الحقل مع البقاء ضمن الحدود المرئية. منتقي الزوايا وأداة اختيار الألوان هما مثالان جيدان على السمة DropDownDiv
.
يتم استخدام WidgetDiv
لتوفير
أدوات تحرير لا تكون داخل صندوق. تستخدم حقول الأرقام
WidgetDiv لتغطية الحقل بمربع إدخال نص HTML. بينما تتعامل أداة 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
في سياق null
في DropDownDiv
. وفي WidgetDiv
، يتم استدعائها في سياق WidgetDiv
. في كلتا الحالتين، من الأفضل استخدام دالة
bind
عند تمرير دالة التخلص، كما هو موضّح في المثالين التاليين
DropDownDiv
وWidgetDiv
أعلاه.
← للحصول على معلومات حول التخلص من المحتوى لا يقتصر على التخلص من أدوات التحرير، يُرجى الاطّلاع على القسم التخلص من المحتوى.
تحديث شاشة العرض في الحظر
تُستخدَم الدالة render_
لتعديل عرض الحقل ضمن الحظر لمطابقة قيمته الداخلية.
تشمل الأمثلة الشائعة ما يلي:
- تغيير النص (قائمة منسدلة)
- تغيير اللون (اللون)
الإعدادات التلقائية
تضبط دالة render_
التلقائية النص المعروض على نتيجة دالة getDisplayText_
. تعرض الدالة getDisplayText_
سمة value_
الخاصة بالحقل
التي يتم إرسالها إلى سلسلة بعد اقتطاعها لمراعاة الحد الأقصى لطول النص.
إذا كنت تستخدم طريقة العرض التلقائية لحظر المحتوى وكان السلوك التلقائي للنص متوافقًا مع الحقل، لن تحتاج إلى إلغاء render_
.
إذا كان السلوك التلقائي للنص متاحًا في الحقل الخاص بك، وكانت عرض الحقل ضمن الحظر يحتوي على عناصر ثابتة إضافية، يمكنك استدعاء الدالة render_
التلقائية، ولكن سيظل عليك تجاوزها من أجل تعديل حجم الحقل.
إذا كان السلوك التلقائي للنص لا يتناسب مع حقلك أو إذا كان عرض الحقل في الحظر يتضمن عناصر ديناميكية إضافية، ستحتاج إلى تخصيص
الوظيفة render_
.
تخصيص العرض
إذا كان سلوك العرض التلقائي لا يعمل مع حقلك، ستحتاج إلى تحديد سلوك العرض المخصَّص. وقد يشمل ذلك أي شيء بدءًا من تعيين نص عرض مخصص، إلى تغيير عناصر الصورة، إلى تحديث ألوان الخلفية.
جميع التغييرات في سمات DOM قانونية، الشيء الوحيد الذي يجب تذكره هما:
- يجب التعامل مع إنشاء نموذج العناصر في المستند (DOM) أثناء الإعداد لأنه أكثر كفاءة.
- يجب دائمًا تعديل السمة
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
. سترغب في الوصول إلى اللون
من خلال خاصية نمط الكتلة.
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;
}
}
التسلسل
يدور التسلسل حول حفظ حالة الحقل بحيث يمكن إعادة تحميله في مساحة العمل لاحقًا.
تتضمن حالة مساحة العمل دائمًا قيمة الحقل، ولكن يمكن أن تتضمن أيضًا حالة أخرى، مثل حالة واجهة مستخدم الحقل. على سبيل المثال، إذا كان الحقل عبارة عن خريطة قابلة للتكبير/التصغير تسمح للمستخدم بتحديد البلدان، فيمكنك أيضًا تسلسل مستوى التكبير/التصغير.
إذا كان الحقل قابلاً للتسلسل، يجب ضبط السمة SERIALIZABLE
على
true
.
يوفر بشكل أساسي مجموعتَين من عناصر الجذب للتسلسل. يعمل أحدهما مع نظام تسلسل JSON الجديد، بينما يعمل الزوج الآخر مع نظام تسلسل XML القديم.
saveState
وloadState
saveState
وloadState
هما أداتان للتسلسل الذي يعمل مع نظام تسلسل 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
. يُستخدم هذا من خلال الحقول التي تشير عادةً إلى حالة تسلسلية باستخدام serializer مختلف (مثل نماذج البيانات الاحتياطية). تشير المَعلمة إلى أنّ الحالة المُشار إليها لن تكون متاحة عند إلغاء تسلسل الكتلة، لذا يجب أن ينفّذ الحقل جميع عمليات التسلسل بنفسه. على سبيل المثال، يكون هذا صحيحًا عندما تكون كتلة فردية
متسلسلة، أو عندما يتم نسخ كتلة.
هناك حالتا استخدام شائعتان لذلك هما:
- عند تحميل كتلة فردية في مساحة عمل لا يتوفّر فيها نموذج بيانات الاحتياطية، يحتوي الحقل على معلومات كافية في حالته الخاصة لإنشاء نموذج بيانات جديد.
- عند نسخ كتلة، يقوم الحقل دائمًا بإنشاء نموذج بيانات احتياطي جديد بدلاً من الإشارة إلى نموذج موجود.
أحد الحقول التي تستخدم هذا هو حقل المتغير المضمّن. تعرض هذه الدالة عادةً معرِّف المتغيّر الذي يشير إليه بشكل متسلسل، ولكن إذا كانت القيمة doFullSerialization
صحيحة، تعرض كل حالاتها بشكل متسلسل.
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
ما إذا كان يجب أن يحتوي الحقل على واجهة مستخدم للإشارة إلى إمكانية التفاعل معه. القيمة التلقائية هي true
.
تحدّد السمة SERIALIZABLE
ما إذا كان يجب إنشاء تسلسل للحقل. يكون
القيمة الافتراضية هي false
. إذا كانت السمة true
، قد تحتاج إلى توفير وظيفتَي التسلسل وإلغاء التسلسل (يمكنك الاطّلاع على التسلسل).
تخصيص المؤشر
تحدّد السمة CURSOR
المؤشر الذي يراه المستخدمون عند تمرير مؤشر الماوس فوق حقلك. يجب أن تكون القيمة سلسلة صالحة لمؤشر CSS. يتم ضبط هذا الإعداد تلقائيًا على المؤشر الذي
يتم تحديده من قِبل .blocklyDraggable
، وهو مؤشر الإمساك.