יצירת סוג חדש של שדה

לפני שיוצרים סוג שדה חדש, כדאי לבדוק אם אחד מהשדות האחרים אמצעי תשלום להתאמה אישית של השדות לפי הצרכים שלך. אם האפליקציה צריכה לאחסן או ליצור ממשק משתמש חדש לסוג ערך קיים, תצטרכו ליצור סוג שדה חדש.

כדי ליצור שדה חדש:

  1. הטמיעו constructor.
  2. רושמים מפתח JSON ומטמיעים את fromJson.
  3. טיפול באתחול של האירוע וממשק המשתמש בבלוק מאזינים.
  4. השלכת כינויים של מאזינים לאירועים (השלכת ממשק המשתמש מתבצעת עבור עבורך).
  5. יישום של טיפול בערך.
  6. כדאי להוסיף ייצוג טקסטואלי של ערך השדה, לשיפור הנגישות.
  7. אפשר להוסיף עוד פונקציונליות, למשל:
  8. מגדירים היבטים נוספים בשדה, כמו:

הקטע הזה מניח שקראתם את התוכן ואתם מכירים אותו המבנה של שדה.

דוגמה לשדה מותאם אישית זמינה בקטע שדות מותאמים אישית הדגמה (דמו) הקצר הזה. התשובות שלך יעזרו לנו להשתפר.

הטמעת constructor

ה-constructor של השדה אחראי להגדרת הערך הראשוני של השדה ואם רוצים, אפשר להגדיר גם מקומי כלי התיקוף. ההתאמה האישית ל-constructor של השדה קוראים במהלך אתחול בלוק המקור, אם בלוק המקור מוגדר ב-JSON או ב-JavaScript. כלומר, הערכים אין לשדה גישה לבלוק המקור במהלך הבנייה.

דוגמת הקוד הבאה יוצרת שדה מותאם אישית בשם GenericField:

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

    this.SERIALIZABLE = true;
  }
}

חתימת שיטה

בוני שדות בדרך כלל לוקחים ערך ומאמת מקומי. הערך הוא אופציונלי, ואם לא מעבירים ערך (או מעבירים ערך שנכשל במחלקה) אימות) ייעשה שימוש בערך ברירת המחדל של מחלקה-על. עבור המחלקה Field המוגדרת כברירת מחדל, הערך הזה הוא null. אם לא רוצים להגדיר את ברירת המחדל חשוב להזין ערך מתאים. פרמטר האימות הוא רק קיימים בשדות שניתנים לעריכה, ובדרך כלל מסומן כאופציונלי. מידע נוסף על מאמתים בכלי האימות מסמכים.

מבנה

הלוגיקה בתוך ה-constructor צריכה לפעול לפי התהליך הבא:

  1. קוראים ל-Super constructor שעובר בירושה (כל השדות המותאמים אישית צריכים לרשת Blockly.Field או אחד ממחלקות המשנה שלו) כדי לאתחל את הערך כראוי ומגדירים את המאמת המקומי לשדה.
  2. אם ניתן לערוך את השדה בסדרה, מגדירים את המאפיין המתאים constructor. שדות שניתנים לעריכה חייבים להיות ניתנים לעריכה הסדרתית, ושדות ניתנים לעריכה כברירת מחדל, לכן כדאי להגדיר את המאפיין הזה כ-TRUE, אלא אם יודעים הוא לא יכול להיות בפורמט סידורי.
  3. אופציונלי: אפשר לבצע התאמה אישית נוספת (לדוגמה, שדות של תוויות). מאפשרת להעביר מחלקת css, שלאחר מכן מוחלת על הטקסט).

JSON ורישום

בבלוק JSON הגדרות, מתוארים באמצעות מחרוזת (למשל field_number, field_textinput). חסימה מאפשרת לשמור מפה ממחרוזות אלה לאובייקטים שבשדה ולקריאות fromJson על האובייקט המתאים במהלך הבנייה.

צריך להפעיל את Blockly.fieldRegistry.register כדי להוסיף את סוג השדה שלך למפה הזו. עובר במחלקת השדה כארגומנט השני:

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

בנוסף, עליך להגדיר את הפונקציה fromJson. ההטמעה צריכה פעולת חיסור ראשונה של כל string טבלה הפניות באמצעות replaceMessageReferences, ולהעביר את הערכים ל-constructor.

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_ בשדה.

אירועי קלט

כברירת מחדל, בשדות ברירת המחדל מתועדים אירועי הסבר קצר ואירועי 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 מותאמת אישית. השיטה הזו של אירועי קישור מסננת נגיעות משניות במהלך וגרירה. אם רוצים שה-handler יפעל גם באמצע גרירה שמתרחשת אפשר להשתמש Blockly.browserEvents.bind מותאמת אישית.

השלכה

אם רשמת פונקציות event listener בהתאמה אישית ב-bindEvents_ של השדה צריך לבטל את ההרשמה שלהם בתוך הפונקציה dispose.

אם אתחלתם את התג בצורה נכונה צפייה של השדה (על ידי צירוף כל רכיבי ה-DOM ל-fieldGroup_), ואז ה-DOM של שדה זה יוסר באופן אוטומטי.

טיפול בערך

← למידע על הערך של שדה לעומת הטקסט שלו, ראו אנטומיה של .

הזמנת אימות

תרשים זרימה שמתאר את הסדר שבו פועלים מאמתים

הטמעת כלי לאימות כיתות

כל שדה יכול לקבל רק ערכים מסוימים. לדוגמה, בשדות של מספרים צריך רק מקבלים מספרים, שדות צבע יכולים לקבל צבעים בלבד וכו'. להבטיח בכיתה ובמקומי מאמתים. הכיתה כלי האימות פועל לפי אותם כללים כמו אימותים מקומיים, אבל הוא גם פועל ב constructor ולכן היא לא אמורה להפנות לבלוק המקור.

כדי להטמיע את מאמת הכיתה של השדה, צריך לבטל את 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, במקום לאמת מחדש כל אחת מהן כל נכס בנפרד.

אפשר להשתמש בדפוס הזה לאימות ערכים מרובי-חלקים גם ב-local אמצעים מאמתים, אבל כרגע אין דרך לאכוף את הדפוס הזה.

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_ במועד המתאים. ניתן להציג כל קוד HTML בעורך שלך, על ידי גלישתו באחד משני תווי div מיוחדים, שנקראים DropDownDiv ואת WidgetDiv, שצפים מעל לשאר ממשק המשתמש של Blockly.

DropDownDiv משמש כדי לספק עורכים שממוקמים בתוך קופסה שמחוברת לשדה מסוים. המכשיר ממקם את עצמו באופן אוטומטי כך שיהיה ליד השדה, ובמקביל להישאר בתוך גבולות גלויים. בוחר הזווית ובוחר הצבעים הם דוגמאות טובות DropDownDiv.

תמונה של הכלי לבחירת זווית

WidgetDiv משמש מספקים עורכים שלא נמצאים בתוך תיבה. בשדות המספרים נעשה שימוש באופרטור WidgetDiv כדי לכסות את השדה באמצעות תיבת קלט של טקסט HTML. בזמן התפריט הנפתח את המיקום בשבילכם, ב-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 של הווידג'ט אבל עליך להשליך באופן ידני את כל פונקציות event listener שיש לך שהוחלו על הרכיבים האלה.

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_ אבל עדיין תצטרכו לעקוף אותה כדי לעדכן את size.

אם התנהגות ברירת המחדל של הטקסט לא פועלת בשדה שלכם, או במסך מהסוג הזה יש רכיבים דינמיים נוספים, שתצטרכו להתאים אישית 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;
  }
}

סריאליזציה

העריכה בהמשכים עוסקת בשמירת של השדה, כדי שיהיה אפשר לטעון אותו מחדש לסביבת העבודה מאוחר יותר.

המצב של סביבת העבודה תמיד כולל את הערך של השדה, אבל הוא יכול גם להיות כוללים מצב אחר, כמו מצב ממשק המשתמש של השדה. לדוגמה, אם היה מפה מותאמת אישית שאפשרה למשתמש לבחור מדינות, ניתן גם לעשות סריאליזציה של רמת המרחק מהתצוגה.

אם השדה ניתן לעריכה בסדרה, צריך להגדיר את המאפיין SERIALIZABLE לערך true.

Blockly מספק שתי קבוצות של הוקים (hooks) לעריכה סריאלית לשדות. זוג אחד של הוקים פועל עם מערכת העריכה החדשה של JSON, והזוג השני עובד עם במערכת הישנה של יצירת סריאליזציה ל-XML.

saveState וגם loadState

saveState ו-loadState הם קטעי הוק (hooks) לסריאליזציה שפועלים עם קובץ ה-JSON החדש מערכת עיבוד סריאליזציה.

במקרים מסוימים אין צורך לספק את הפרטים האלה, מפני שברירת המחדל בפועל יפעלו. אם (1) השדה הוא מחלקה ישירה של הבסיס Blockly.Field class, (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 הם קטעי הוק (hooks) לסריאליזציה שפועלים עם ה-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, יכול להיות שיהיה עליך לספק פונקציות סריאליזציה וdeserialization (ראו סריאליזציה).

התאמה אישית של הסמן

המאפיין CURSOR קובע את הסמן שהמשתמשים רואים כשהם מעבירים את העכבר מעליו השדה שלך. היא צריכה להיות מחרוזת חוקית של סמן CSS. ברירת המחדל היא של הסמן מוגדר על ידי .blocklyDraggable, שהוא סמן האחיזה.