नया फ़ील्ड टाइप बनाना

कोई नया फ़ील्ड टाइप बनाने से पहले, देखें कि अन्य फ़ील्ड टाइप में तरीके का इस्तेमाल करें. अगर आपके ऐप्लिकेशन को नया मान टाइप या किसी मौजूदा वैल्यू टाइप के लिए नया यूज़र इंटरफ़ेस (यूआई) बनाना हो, तो आपको शायद एक नया फ़ील्ड टाइप बनाना पड़े.

नया फ़ील्ड बनाने के लिए, यह तरीका अपनाएं:

  1. कंस्ट्रक्टर लागू करें.
  2. JSON कुंजी रजिस्टर करें और fromJson लागू करें.
  3. ऑन-ब्लॉक यूज़र इंटरफ़ेस (यूआई) और इवेंट को शुरू करने की प्रोसेस मैनेज करें लिसनर.
  4. इवेंट लिसनर को मैनेज करना (यूज़र इंटरफ़ेस (यूआई) का डिस्पोज़ल, आप).
  5. वैल्यू हैंडलिंग लागू करें.
  6. सुलभता के लिए, अपने फ़ील्ड की वैल्यू को टेक्स्ट के तौर पर दिखाएं.
  7. अतिरिक्त सुविधाएं जोड़ें, जैसे:
  8. अपने फ़ील्ड के दूसरे पहलुओं को कॉन्फ़िगर करें, जैसे:

इस सेक्शन में यह माना गया है कि आपने यहां मौजूद कॉन्टेंट को पढ़ लिया है और आपको उसके बारे में जानकारी है इसकी एनाटॉमी फ़ील्ड.

कस्टम फ़ील्ड के उदाहरण के लिए कस्टम फ़ील्ड देखें डेमो को अपनाएं.

कंस्ट्रक्टर को लागू करना

फ़ील्ड का कंस्ट्रक्टर, फ़ील्ड की शुरुआती वैल्यू को सेट अप करने के लिए ज़िम्मेदार है और वैकल्पिक रूप से लोकल पुष्टि करने वाला प्रोग्राम. कस्टम फ़ील्ड के कंस्ट्रक्टर को, सोर्स ब्लॉक को शुरू करने के दौरान कॉल किया जाता है, भले ही सोर्स ब्लॉक को JSON या JavaScript में तय किया गया है या नहीं. इसलिए, कस्टम निर्माण के दौरान फ़ील्ड को सोर्स ब्लॉक का ऐक्सेस नहीं है.

यह कोड सैंपल, GenericField नाम का एक कस्टम फ़ील्ड बनाता है:

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

    this.SERIALIZABLE = true;
  }
}

मेथड सिग्नेचर

फ़ील्ड कंस्ट्रक्टर आम तौर पर, एक वैल्यू और एक लोकल वैलिडेटर लेते हैं. मान है वैकल्पिक है और अगर आपने कोई वैल्यू पास नहीं की है या कोई ऐसी वैल्यू पास की है जो क्लास में फ़ेल हो गई है पुष्टि करें) तो सुपर क्लास की डिफ़ॉल्ट वैल्यू का इस्तेमाल किया जाएगा. डिफ़ॉल्ट Field क्लास, वह मान null है. अगर आपको वह डिफ़ॉल्ट मान है, तो उपयुक्त मान पास करना न भूलें. पुष्टि करने वाला पैरामीटर सिर्फ़ यह बदलाव किए जा सकने वाले फ़ील्ड के लिए मौजूद होता है. आम तौर पर, इसे 'ज़रूरी नहीं' के तौर पर मार्क किया जाता है. ज़्यादा जानें वैलिडेटर में, पुष्टि करने वाले प्रोग्राम के बारे में जानकारी दस्तावेज़.

बनावट

आपके कंस्ट्रक्टर के अंदर का लॉजिक इस फ़्लो के बाद होना चाहिए:

  1. इनहेरिट किए गए सुपर कंस्ट्रक्टर को कॉल करें (सभी कस्टम फ़ील्ड इनसे इनहेरिट किए जाने चाहिए Blockly.Field या उसकी किसी सब-क्लास) का इस्तेमाल करें. ऐसा करके, वैल्यू को सही तरीके से शुरू किया जा सकता है और अपने फ़ील्ड के लिए लोकल वैलिडेटर सेट करें.
  2. अगर आपके फ़ील्ड को क्रम से लगाया जा सकता है, तो इससे जुड़ी प्रॉपर्टी कंस्ट्रक्टर है. जिन फ़ील्ड में बदलाव किया जा सकता है उन्हें क्रम से लगाया जा सकता हो. साथ ही, फ़ील्ड में बदलाव किया जा सकता हो डिफ़ॉल्ट रूप से, इसलिए अगर आपको पता नहीं है कि आपको इस प्रॉपर्टी को सही पर सेट करना चाहिए ऐसा नहीं होना चाहिए कि उसे क्रम से लगाया जा सके.
  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);
};

शुरू हो रहा है

जब आपका फ़ील्ड बनाया जाता है, तो उसमें आम तौर पर सिर्फ़ एक वैल्यू होती है. शुरुआत में, डीओएम बनाया जाता है और मॉडल बनाया जाता है (अगर फ़ील्ड के पास एक मॉडल है) और इवेंट सीमित हैं.

ब्लॉक करने पर दिखने वाला डिसप्ले

शुरू करने के दौरान, अपनी ज़रूरत के हिसाब से किसी भी चीज़ को बनाने की ज़िम्मेदारी आपकी है फ़ील्ड के ऑन-ब्लॉक डिसप्ले के लिए.

डिफ़ॉल्ट, बैकग्राउंड, और टेक्स्ट

डिफ़ॉल्ट initView फ़ंक्शन, हल्के रंग का rect एलिमेंट बनाता है और text एलिमेंट. अगर आपको फ़ील्ड में इन दोनों के साथ-साथ कुछ अतिरिक्त और गुडी, अपने शेष को जोड़ने से पहले सुपर क्लास initView फ़ंक्शन को कॉल करें DOM एलिमेंट. अगर आपको इनमें से किसी एक फ़ील्ड का इस्तेमाल करना हो, दोनों नहीं, तो एलिमेंट जिनमें आप createBorderRect_ या createTextElement_ फ़ंक्शन का इस्तेमाल कर सकते हैं.

डीओएम कंस्ट्रक्शन को पसंद के मुताबिक बनाना

अगर आपका फ़ील्ड एक सामान्य टेक्स्ट फ़ील्ड है (जैसे, टेक्स्ट इनपुट), आपके लिए डीओएम कंस्ट्रक्शन को मैनेज किया जाएगा. अगर ऐसा नहीं किया जाता है, तो आपको बदलाव करना होगा initView फ़ंक्शन का इस्तेमाल करके ऐसे डीओएम एलिमेंट बनाएं जिनकी आपको ज़रूरत पड़ेगी आने वाले समय में रेंडर होने में आपकी मदद कर सकते हैं.

उदाहरण के लिए, ड्रॉपडाउन फ़ील्ड में इमेज और टेक्स्ट, दोनों हो सकते हैं. initView में एक इमेज एलिमेंट और एक टेक्स्ट एलिमेंट बनाता है. फिर, render_ के दौरान यह ऐक्टिव एलिमेंट को दिखाता है और दूसरे एलिमेंट को छिपा देता है. चुना गया विकल्प.

डीओएम एलिमेंट बनाने के लिए, Blockly.utils.dom.createSvgElement तरीका या ट्रेडिशनल डीओएम क्रिएशन का इस्तेमाल करना तरीकों का इस्तेमाल करना होगा.

फ़ील्ड के ऑन-ब्लॉक डिसप्ले के लिए ज़रूरी शर्तें:

  • सभी डीओएम एलिमेंट, फ़ील्ड के fieldGroup_ के चाइल्ड होने चाहिए. फ़ील्ड ग्रुप अपने-आप बन जाता है.
  • सभी डीओएम एलिमेंट, फ़ील्ड के रिपोर्ट किए गए डाइमेंशन के अंदर होने चाहिए.

ज़्यादा जानकारी के लिए, रेंडरिंग सेक्शन देखें.

टेक्स्ट सिंबल जोड़ना

यदि आप किसी फ़ील्ड के टेक्स्ट में प्रतीक जोड़ना चाहते हैं (जैसे कोण फ़ील्ड की डिग्री का चिह्न) का उपयोग करके, आप प्रतीक तत्व (आमतौर पर <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 तक और ओवरराइड करें 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_ पर क्लिक करें और उचित समय पर कॉल करें. कोई भी एचटीएमएल कोड दिखाया जा सकता है इसमें दो खास divs में से एक को रैप करें, जिसे ड्रॉपडाउन ड्रॉपडाउन कहा जाता है. और WidgetDiv, जो Blockly के यूआई के ऊपर फ़्लोट करता है.

DropDownDiv का इस्तेमाल एडिटर के लिए किया जाता है, जो कनेक्ट किए गए बॉक्स के अंदर रहते हैं फ़ील्ड में. रहने के दौरान, यह अपने-आप फ़ील्ड के पास की जगह पर आ जाता है दिखाई देने वाली सीमाओं के भीतर हो. ऐंगल पिकर और कलर पिकर, DropDownDiv.

ऐंगल पिकर की इमेज

WidgetDiv का इस्तेमाल इन कामों के लिए किया जाता है ऐसे संपादक उपलब्ध कराएं जो बॉक्स के अंदर नहीं रहते. संख्या फ़ील्ड WidgetDiv से फ़ील्ड को एचटीएमएल टेक्स्ट इनपुट बॉक्स से कवर किया जाएगा. जब ड्रॉपडाउन को यह आपकी जगह की जानकारी तय करता है, लेकिन 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);
}

साफ़ किया जा रहा है

ड्रॉपडाउन मेन्यू और WidgetDiv, दोनों ही विजेट के एचटीएमएल को बंद करते हैं एलिमेंट का इस्तेमाल करने के लिए, आपको अपने इवेंट लिसनर को मैन्युअल तौर पर हटाना होगा उन एलिमेंट पर लागू की जाती है.

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 के संदर्भ में किया गया है. दोनों ही मामलों में तो आपके लिए सबसे अच्छा तरीका यह है कि बाइंड करें डिसपोज़ फ़ंक्शन पास करते समय फ़ंक्शन का इस्तेमाल करें, जैसा कि ऊपर DropDownDiv में दिखाया गया है और WidgetDiv उदाहरण.

→ संपादकों को नष्ट करने के बारे में जानकारी के लिए, देखें कि निपटना.

ब्लॉक किए गए डिसप्ले की सेटिंग अपडेट की जा रही है

फ़ील्ड के ऑन-ब्लॉक डिसप्ले को मिलान करने के लिए, उसे अपडेट करने के लिए render_ फ़ंक्शन का इस्तेमाल किया जाता है अपनी वैल्यू तय करें.

सामान्य उदाहरणों में ये शामिल हैं:

  • टेक्स्ट बदलना (ड्रॉपडाउन)
  • रंग (रंग) बदलें

डिफ़ॉल्ट

डिफ़ॉल्ट render_ फ़ंक्शन, डिसप्ले टेक्स्ट को getDisplayText_ फ़ंक्शन का इस्तेमाल करना होगा. getDisplayText_ फ़ंक्शन, फ़ील्ड की value_ प्रॉपर्टी दिखाता है अधिकतम टेक्स्ट के हिसाब से काट-छांट करने के बाद, स्ट्रिंग पर कास्ट करें लंबाई.

अगर डिफ़ॉल्ट ऑन-ब्लॉक डिसप्ले और डिफ़ॉल्ट टेक्स्ट ऐक्शन का इस्तेमाल किया जा रहा है आपके फ़ील्ड के लिए काम करता है, तो आपको render_ को ओवरराइड करने की ज़रूरत नहीं है.

अगर डिफ़ॉल्ट टेक्स्ट ऐक्शन आपके फ़ील्ड के लिए काम करता है, लेकिन फ़ील्ड ऑन-ब्लॉक है डिसप्ले में अतिरिक्त स्टैटिक एलिमेंट मौजूद हैं, इसलिए डिफ़ॉल्ट render_ को कॉल किया जा सकता है फ़ंक्शन का उपयोग करने के लिए, लेकिन आपको अभी भी फ़ील्ड के साइज़.

अगर डिफ़ॉल्ट टेक्स्ट व्यवहार आपकी फ़ील्ड या आपके फ़ील्ड के ऑन-ब्लॉक डिसप्ले में अतिरिक्त डाइनैमिक एलिमेंट होते हैं. इसलिए, आपको अपनी ज़रूरत के मुताबिक render_ फ़ंक्शन के बारे में ज़्यादा जानें.

रेंडर को ओवरराइड करना है या नहीं, यह फ़ैसला लेने का तरीका बताने वाला फ़्लोचार्ट_

रेंडरिंग को पसंद के मुताबिक बनाना

अगर डिफ़ॉल्ट रेंडरिंग व्यवहार आपके फ़ील्ड के लिए काम नहीं करता है, तो आपको कस्टम रेंडरिंग व्यवहार को परिभाषित किया जा सकता है. इसमें कस्टम सेटिंग, जैसे कि बैकग्राउंड के रंगों को अपडेट करने, इमेज एलिमेंट बदलने, और डिसप्ले टेक्स्ट इस्तेमाल करने का तरीका.

डीओएम एट्रिब्यूट में किए गए सभी बदलाव कानूनी होते हैं. इसलिए, सिर्फ़ इन दो चीज़ों को याद रखना ज़रूरी है:

  1. डीओएम क्रिएशन को शुरू करना, ज़्यादा कारगर साबित होते हैं.
  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 तरीके को बदलना होगा. आप ऐसा करना चाहेंगे ब्लॉक की स्टाइल प्रॉपर्टी से रंग ऐक्सेस करें.

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, फ़ील्ड के लिए सीरियलाइज़ेशन हुक के दो सेट देता है. एक जोड़ी हुक नए JSON सीरियलाइज़ेशन सिस्टम के साथ काम करता है और दूसरा जोड़ा पुराना एक्सएमएल सीरियलाइज़ेशन सिस्टम.

saveState और loadState

saveState और loadState, सीरियलाइज़ेशन वाले हुक हैं, जो नए JSON के साथ काम करते हैं सीरियलाइज़ेशन सिस्टम.

कुछ मामलों में आपको इन्हें उपलब्ध कराने की ज़रूरत नहीं होती, क्योंकि डिफ़ॉल्ट लागू करने से काम हो जाएगा. अगर (1) आपका फ़ील्ड, बेस का डायरेक्ट सब-क्लास है Blockly.Field क्लास, (2) आपकी वैल्यू JSON को क्रम में लगाई जा सकती है type दिखेगा, और (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 भी मिलता है. यह है उन फ़ील्ड में इस्तेमाल किया जाता है जो आम तौर पर किसी दूसरी सीरियलाइज़र (जैसे, बैकिंग डेटा मॉडल) ऐसे पैरामीटर सिग्नल जो ब्लॉक को डीसीरियलाइज़ (पार्स) करने पर, रेफ़रेंस स्थिति उपलब्ध नहीं होगी, इसलिए फ़ील्ड में क्रम से लगाए जाने वाले सभी काम खुद करने चाहिए. उदाहरण के लिए, यह तब सही होता है, जब जब किसी ब्लॉक को क्रम से लगाया जाता है या जब किसी ब्लॉक को कॉपी करके चिपकाया जाता है.

इसके लिए इस्तेमाल के दो सामान्य उदाहरण हैं:

  • जब किसी एक ब्लॉक को ऐसे फ़ाइल फ़ोल्डर में लोड किया जाता है जिसमें बैकिंग डेटा मॉडल मौजूद नहीं है, फ़ील्ड में नया डेटा मॉडल बनाएं.
  • जब किसी ब्लॉक को कॉपी करके चिपकाया जाता है, तो फ़ील्ड हमेशा नई बैकिंग बनाता है डेटा मॉडल का उपयोग करें.

इसका इस्तेमाल करने वाला एक फ़ील्ड, बिल्ट-इन वैरिएबल फ़ील्ड है. आम तौर पर, यह क्रम से लगाई जाती है जिस वैरिएबल का आईडी दिया जा रहा है उसका आईडी. हालांकि, अगर 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, सीरियलाइज़ेशन वाले हुक हैं, जो पुराने एक्सएमएल के साथ काम करते हैं सीरियलाइज़ेशन सिस्टम. ये हुक तभी इस्तेमाल करें, जब आपको ज़रूरी हो (जैसे कि आप काम कर रहे हों ऐसे पुराने कोड बेस पर स्टोर करें जो अब तक माइग्रेट नहीं हुआ है, तो saveState का इस्तेमाल करें और loadState.

आपके toXml फ़ंक्शन को एक एक्सएमएल नोड दिखना चाहिए, जो फ़ील्ड में जोड़ दें. और आपके fromXml फ़ंक्शन को उसी एक्सएमएल नोड को स्वीकार और लागू करना चाहिए फ़ील्ड में नहीं डालना होगा.

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 प्रॉपर्टी की मदद से, यह तय किया जाता है कि उपयोगकर्ताओं को किस पेज पर कर्सर घुमाया जाएगा आपका फ़ील्ड. यह एक मान्य सीएसएस कर्सर स्ट्रिंग होनी चाहिए. यह कर्सर को डिफ़ॉल्ट रूप से सेट करता है .blocklyDraggable से तय किया गया, जो कि ग्रैब कर्सर है.