एक्सटेंशन और म्यूटर

एक्सटेंशन ऐसे फ़ंक्शन होते हैं जो किसी टाइप के हर ब्लॉक पर ठीक वैसे ही चलते हैं जैसे ब्लॉक बनाया गया. ये अक्सर किसी ब्लॉक में कुछ कस्टम कॉन्फ़िगरेशन या व्यवहार जोड़ते हैं.

म्यूटेटर एक खास तरह का एक्सटेंशन होता है, जो कस्टम सीरियलाइज़ेशन को जोड़ता है, और कभी-कभी यूज़र इंटरफ़ेस (यूआई) का इस्तेमाल करके ब्लॉक करना होता है.

एक्सटेंशन

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

// This extension sets the block's tooltip to be a function which displays
// the parent block's tooltip (if it exists).
Blockly.Extensions.register(
    'parent_tooltip_extension',
    function() { // this refers to the block that the extension is being run on
      var thisBlock = this;
      this.setTooltip(function() {
        var parent = thisBlock.getParent();
        return (parent && parent.getInputsInline() && parent.tooltip) ||
            Blockly.Msg.MATH_NUMBER_TOOLTIP;
      });
    });

एक्सटेंशन को "रजिस्टर किया गया" होना चाहिए ताकि उन्हें किसी स्ट्रिंग के साथ जोड़ा जा सके बटन दबाएं. इसके बाद, इस स्ट्रिंग कुंजी को अपनी extensions प्रॉपर्टी को असाइन किया जा सकता है ब्लॉक टाइप का JSON परिभाषा एक्सटेंशन को ब्लॉक करें.

{
 //...,
 "extensions": ["parent_tooltip_extension",]
}

एक साथ कई एक्सटेंशन भी जोड़े जा सकते हैं. ध्यान दें कि extensions प्रॉपर्टी की एक कलेक्शन होनी चाहिए. भले ही, सिर्फ़ एक एक्सटेंशन लागू किया जा रहा हो.

{
  //...,
  "extensions": ["parent_tooltip_extension", "break_warning_extension"],
}

मिक्सिन्स

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

Blockly.Extensions.registerMixin('my_mixin', {
  someProperty: 'a cool value',

  someMethod: function() {
    // Do something cool!
  }
))`

मिक्सिन से जुड़ी स्ट्रिंग कुंजियों का रेफ़रंस JSON में, किसी भी दूसरी कुंजी की तरह ही लिया जा सकता है एक्सटेंशन चुनें.

{
 //...,
 "extensions": ["my_mixin"],
}

म्यूटेटर

म्यूटेटर एक खास तरह का एक्सटेंशन होता है, जो अतिरिक्त सीरियलाइज़ेशन जोड़ता है सेव और लोड किया जाता है). उदाहरण के लिए, बिल्ट-इन controls_if और list_create_with ब्लॉक को क्रम से लगाने की ज़रूरत है, ताकि कि कितने इनपुट सेव किए जा सकते हैं.

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

क्रम से लगाने का तरीका देखें इसके लिए, पेज आपको म्यूटेटर की ज़रूरत कब पड़ती है और कब नहीं इसके बारे में ज़्यादा जानकारी.

म्यूटेटर की मदद से उपयोगकर्ताओं को पहले से मौजूद यूज़र इंटरफ़ेस (यूआई) भी मिलता है, ताकि वे ब्लॉक का आकार बदल सकें. तो आपके पास कुछ वैकल्पिक तरीके हैं.

सीरियलाइज़ेशन हुक

म्यूटेटर के पास सीरियलाइज़ेशन वाले दो हुक होते हैं, जिनके साथ वे काम करते हैं. एक जोड़ी हुक नए JSON सीरियलाइज़ेशन सिस्टम के साथ काम करता है और दूसरा जोड़ा पुराना एक्सएमएल सीरियलाइज़ेशन सिस्टम. आपको इनमें से कम से कम एक जोड़ा देना होगा.

payExtraState और loadExtraState

saveExtraState और loadExtraState, सीरियलाइज़ेशन वाले हुक हैं, जो नया JSON सीरियलाइज़ेशन सिस्टम. saveExtraState, क्रम में लगाए जा सकने वाले JSON को दिखाता है वह वैल्यू जो ब्लॉक की अतिरिक्त स्थिति को दिखाती है और loadExtraState उसी JSON को क्रम से लगाने वाली वैल्यू को स्वीकार करता है. साथ ही, उसे ब्लॉक पर लागू करता है.

// These are the serialization hooks for the lists_create_with block.
saveExtraState: function() {
  return {
    'itemCount': this.itemCount_,
  };
},

loadExtraState: function(state) {
  this.itemCount_ = state['itemCount'];
  // This is a helper function which adds or removes inputs from the block.
  this.updateShape_();
},

मिलने वाला JSON ऐसा दिखेगा:

{
  "type": "lists_create_with",
  "extraState": {
    "itemCount": 3 // or whatever the count is
  }
}
कोई राज्य नहीं

सीरियल बनाने के दौरान, अगर आपका ब्लॉक डिफ़ॉल्ट स्थिति में है, तो इसे दिखाने के लिए, saveExtraState तरीका null दिखा सकता है. अगर आपके saveExtraState तरीका null दिखाता है. इसके बाद, इसमें कोई extraState प्रॉपर्टी नहीं जोड़ी जाती है JSON. इससे आपकी सेव की गई फ़ाइल का साइज़ छोटा रहता है.

पूरा सीरियलाइज़ेशन और बैकिंग डेटा

saveExtraState को एक doFullSerialization पैरामीटर भी मिलता है. हालांकि, ऐसा करना ज़रूरी नहीं है. यह का इस्तेमाल ऐसे ब्लॉक के लिए किया जाता है जो रेफ़रंस स्टेट को किसी दूसरे सीरियलाइज़र (जैसे, बैकिंग डेटा मॉडल) ऐसे पैरामीटर सिग्नल जो ब्लॉक को डीसीरियलाइज़ (पार्स) करने पर, रेफ़रेंस स्थिति उपलब्ध नहीं होगी, इसलिए ब्लॉक में, बैकिंग की सभी स्थिति को क्रम से लगाना चाहिए. उदाहरण के लिए, यह जब किसी व्यक्तिगत ब्लॉक को क्रम से लगाया जाता है या जब किसी ब्लॉक को कॉपी करके चिपकाया जाता है, तब 'सही' होता है.

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

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

इसका इस्तेमाल करने वाले कुछ ब्लॉक @blockly/block-shareable-procedures ब्लॉक. आम तौर पर वे बैकिंग डेटा मॉडल के रेफ़रंस को सीरियल के तौर पर इस्तेमाल करते हैं, जिसमें उनकी स्थिति सेव की जाती है. हालांकि, अगर doFullSerialization पैरामीटर सही है, तो वे सभी उनके राज्य का नाम है. शेयर की जा सकने वाली प्रोसेस के ब्लॉक का इस्तेमाल करके, यह पक्का किया जाता है कि जब वे कॉपी करके चिपकाया जाता है, तो वे मौजूदा मॉडल के साथ काम करता है.

म्यूटेशनToDom और domToMutation

mutationToDom और domToMutation, सीरियलाइज़ेशन वाले हुक हैं, जो पुराना एक्सएमएल सीरियलाइज़ेशन सिस्टम. ये हुक तभी इस्तेमाल करें, जब आपको (उदाहरण के लिए, आपको आप किसी ऐसे पुराने कोड-बेस पर काम कर रहे हों, जो अभी तक माइग्रेट नहीं हुआ है), अन्यथा इसका उपयोग करें saveExtraState और loadExtraState.

mutationToDom एक एक्सएमएल नोड दिखाता है, जो रोक देता है और domToMutation उसी एक्सएमएल नोड को स्वीकार करता है और स्थिति को ब्लॉक.

// These are the old XML serialization hooks for the lists_create_with block.
mutationToDom: function() {
  // You *must* create a <mutation></mutation> element.
  // This element can have children.
  var container = Blockly.utils.xml.createElement('mutation');
  container.setAttribute('items', this.itemCount_);
  return container;
},

domToMutation: function(xmlElement) {
  this.itemCount_ = parseInt(xmlElement.getAttribute('items'), 10);
  // This is a helper function which adds or removes inputs from the block.
  this.updateShape_();
},

मिलने वाला एक्सएमएल ऐसा दिखेगा:

<block type="lists_create_with">
  <mutation items="3"></mutation>
</block>

अगर आपका mutationToDom फ़ंक्शन शून्य दिखाता है, तो कोई और एलिमेंट नहीं होगा को एक्सएमएल में जोड़ा गया.

यूज़र इंटरफ़ेस (यूआई) हुक

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

अगर आपको अतिरिक्त सीरियल नंबर जोड़ना है, तो आपको इस यूज़र इंटरफ़ेस (यूआई) का इस्तेमाल करने की ज़रूरत नहीं है. आप कस्टम यूज़र इंटरफ़ेस (यूआई) का इस्तेमाल करना, जैसे कि blocks-plus-माइनस प्लगिन उपलब्ध कराता है या आप किसी भी यूज़र इंटरफ़ेस (यूआई) का इस्तेमाल नहीं कर सकते!

लिखें और डीकंपोज़ करें

डिफ़ॉल्ट यूज़र इंटरफ़ेस (यूआई), compose और decompose फ़ंक्शन पर निर्भर करता है.

decompose "विस्फोटक" ब्लॉक को छोटे सब-ब्लॉक में बदल दिया जाएगा, जिसे बाद में आस-पास, जोड़ा और हटाया गया. इस फ़ंक्शन से "टॉप ब्लॉक" मिलना चाहिए जो है म्यूटर फ़ाइल फ़ोल्डर का मुख्य ब्लॉक जिससे सब-ब्लॉक कनेक्ट होते हैं.

इसके बाद, compose सब-ब्लॉक के कॉन्फ़िगरेशन को समझता है और इन कामों के लिए उनका इस्तेमाल करता है मुख्य ब्लॉक में बदलाव कर सकते हैं. इस फ़ंक्शन को "टॉप ब्लॉक" को स्वीकार करना चाहिए जो था पैरामीटर के तौर पर decompose से दिखाया जाता है.

ध्यान दें कि ये फ़ंक्शन "मिले-जुले रूप में" मिलते हैं ब्लॉक को "म्यूटेशन" किया जा रहा है this का इस्तेमाल उस ब्लॉक के बारे में बताने के लिए किया जा सकता है.

// These are the decompose and compose functions for the lists_create_with block.
decompose: function(workspace) {
  // This is a special sub-block that only gets created in the mutator UI.
  // It acts as our "top block"
  var topBlock = workspace.newBlock('lists_create_with_container');
  topBlock.initSvg();

  // Then we add one sub-block for each item in the list.
  var connection = topBlock.getInput('STACK').connection;
  for (var i = 0; i < this.itemCount_; i++) {
    var itemBlock = workspace.newBlock('lists_create_with_item');
    itemBlock.initSvg();
    connection.connect(itemBlock.previousConnection);
    connection = itemBlock.nextConnection;
  }

  // And finally we have to return the top-block.
  return topBlock;
},

// The container block is the top-block returned by decompose.
compose: function(topBlock) {
  // First we get the first sub-block (which represents an input on our main block).
  var itemBlock = topBlock.getInputTargetBlock('STACK');

  // Then we collect up all of the connections of on our main block that are
  // referenced by our sub-blocks.
  // This relates to the saveConnections hook (explained below).
  var connections = [];
  while (itemBlock && !itemBlock.isInsertionMarker()) {  // Ignore insertion markers!
    connections.push(itemBlock.valueConnection_);
    itemBlock = itemBlock.nextConnection &&
        itemBlock.nextConnection.targetBlock();
  }

  // Then we disconnect any children where the sub-block associated with that
  // child has been deleted/removed from the stack.
  for (var i = 0; i < this.itemCount_; i++) {
    var connection = this.getInput('ADD' + i).connection.targetConnection;
    if (connection && connections.indexOf(connection) == -1) {
      connection.disconnect();
    }
  }

  // Then we update the shape of our block (removing or adding iputs as necessary).
  // `this` refers to the main block.
  this.itemCount_ = connections.length;
  this.updateShape_();

  // And finally we reconnect any child blocks.
  for (var i = 0; i < this.itemCount_; i++) {
    connections[i].reconnect(this, 'ADD' + i);
  }
},

saveConnections

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

saveConnections को "टॉप ब्लॉक" स्वीकार करना चाहिए आपके decompose से वापस की गई पैरामीटर के तौर पर काम करता है. अगर saveConnections फ़ंक्शन तय किया गया है, तो Blockly compose पर कॉल करने से पहले कॉल करेंगे.

saveConnections: function(topBlock) {
  // First we get the first sub-block (which represents an input on our main block).
  var itemBlock = topBlock.getInputTargetBlock('STACK');

  // Then we go through and assign references to connections on our main block
  // (input.connection.targetConnection) to properties on our sub blocks
  // (itemBlock.valueConnection_).
  var i = 0;
  while (itemBlock) {
    // `this` refers to the main block (which is being "mutated").
    var input = this.getInput('ADD' + i);
    // This is the important line of this function!
    itemBlock.valueConnection_ = input && input.connection.targetConnection;
    i++;
    itemBlock = itemBlock.nextConnection &&
        itemBlock.nextConnection.targetBlock();
  }
},

पंजीकृत किया जा रहा है

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

// Function signature.
Blockly.Extensions.registerMutator(name, mixinObj, opt_helperFn, opt_blockList);

// Example call.
Blockly.Extensions.registerMutator(
    'controls_if_mutator',
    { /* mutator methods */ },
    undefined,
    ['controls_if_elseif', 'controls_if_else']);
  • name: म्यूटेटर के साथ जोड़ी जाने वाली स्ट्रिंग, ताकि आप इसका इस्तेमाल JSON में कर सकें.
  • mixinObj: एक ऑब्जेक्ट जिसमें म्यूटेशन के कई तरीके होते हैं. उदाहरण के लिए, saveExtraState और loadExtraState.
  • opt_helperFn: एक वैकल्पिक सहायता फ़ंक्शन, जो मिक्सिन मिल जाने के बाद ब्लॉक पर चलाएं.
  • opt_blockList: ब्लॉक टाइप (स्ट्रिंग के तौर पर) की वैकल्पिक कैटगरी, जो डिफ़ॉल्ट म्यूटेटर यूज़र इंटरफ़ेस (यूआई) में फ़्लायआउट में जोड़ा जा सकता है, अगर यूज़र इंटरफ़ेस (यूआई) के तरीके भी तय किया गया है.

ध्यान दें कि एक्सटेंशन के उलट, हर ब्लॉक टाइप में सिर्फ़ एक म्यूटेटर हो सकता है.

{
  //...
  "mutator": "controls_if_mutator"
}

हेल्पर फ़ंक्शन

मिक्सिन के साथ-साथ, एक म्यूटेटर एक हेल्पर फ़ंक्शन रजिस्टर कर सकता है. यह फ़ंक्शन है इसे बनाए जाने के बाद दिए गए टाइप के हर ब्लॉक पर चलाएं और मिक्सinObj जोड़ा गया. इसका इस्तेमाल, किसी म्यूटेशन में अतिरिक्त ट्रिगर या इफ़ेक्ट जोड़ने के लिए किया जा सकता है.

उदाहरण के लिए, अपनी सूची की तरह ब्लॉक में एक हेल्पर जोड़ा जा सकता है, जो आइटम की शुरुआती संख्या:

var helper = function() {
  this.itemCount_ = 5;
  this.updateShape();
}