Uzantılar ve Susturucular

Uzantılar, belirli bir türdeki her bir blokta çalışan bir işlevdir. oluşturuldu. Bunlar genellikle bir bloka özel yapılandırma veya davranış ekler.

Mutator, özel serileştirme ekleyen özel bir uzantı türüdür ve bir yapıya dönüşebilir.

Uzantılar

Uzantılar, belirli bir türdeki her bir blokta çalışan bir işlevdir. oluşturuldu. Özel yapılandırma ekleyebilirler (ör. engellemenin ipucunu ayarlayabilirler) veya özel davranış (ör. engellemeye bir etkinlik işleyici ekleme).

// 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;
      });
    });

Uzantıların "kayıtlı" olması gerekir Böylece, bunlar bir dizeyle ilişkilendirilebilir. tuşuna basın. Daha sonra bu dize anahtarını sayfanızın extensions özelliğine atayabilirsiniz. blok türünün JSON'si tanımını eklememiz gerekir.

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

Ayrıca tek seferde birden fazla uzantı da ekleyebilirsiniz. extensions özelliği bir dizi olmalıdır.

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

Mix'ler

Blockly, eklemek istediğiniz durumlar için bazı özellikleri/yardımcı işlevlerini bir bloka bağlayabilir, ancak bunları hemen çalıştırmaz. Bu mixin kaydedebilirsiniz. nesnesini ifade eder. Mixin nesnesi sonra, bir örneği her seferinde mix'i uygulayan bir işleve sarmalanır. belirtilen blok türünün oluşturulur.

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

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

Mix'lerle ilişkili dize anahtarlarına, diğer tüm içerikler gibi JSON'de referans verilebilir. uzantısına sahip olur.

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

Mutatörler

Mutator, fazladan serileştirme (ekstra durumu) bir engelleme olarak değiştirin. Örneğin, controls_if ve list_create_with blok için ekstra serileştirme gerekiyor sahip oldukları giriş sayısını kaydedebilirler.

Blokunuzun şeklini değiştirmenizin mutlaka gerektiği anlamına gelmediğini unutmayın yardımcı olur. Örneğin, math_number_property bloğu değişiklikleri ancak bunu, değeri zaten serileştirmektedir. Dolayısıyla, yalnızca bir alanı emin olun, gerekir.

Serileştirmeye göz atın sayfa: ve ne zaman ihtiyaç duymadığınızla ilgili daha fazla bilgi edinebilirsiniz.

Mutatörler ayrıca kullanıcıların blokların şekillerini değiştirmeleri için yerleşik bir kullanıcı arayüzü sağlar. bazı isteğe bağlı yöntemler sağlarsınız.

Serileştirme kancaları

Mutatörlerin birlikte çalıştığı iki çift serileştirme kancası vardır. Bir çift kanca yeni JSON serileştirme sistemiyle çalışırken diğer çift XML serileştirme sistemini kullanmanız gerekir. Bu çiftlerden en az birini sağlamanız gerekir.

SaveExtraState ve loadExtraState

saveExtraState ve loadExtraState, aşağıdakilerle çalışan serileştirme kancalarıdır: yeni JSON serileştirme sistemimiz var. saveExtraState, seri hale getirilebilir bir JSON döndürür bloğun fazladan durumunu temsil eden değer ve loadExtraState aynı JSON serileştirilebilir değerini kabul eder ve bunu bloka uygular.

// 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_();
},

Elde edilen JSON aşağıdaki gibi görünür:

{
  "type": "lists_create_with",
  "extraState": {
    "itemCount": 3 // or whatever the count is
  }
}
Durum yok

Blokunuz serileştirildiğinde varsayılan durumundaysa saveExtraState yöntemi, bunu belirtmek için null değerini döndürebilir. Eğer saveExtraState yöntemi null değerini döndürür ve ardından şuna hiçbir extraState özelliği eklenmez: JSON dosyası biçimindedir. Bu, kayıt dosyanızın boyutunu küçük tutar.

Tam serileştirme ve veri yedekleme

saveExtraState ayrıca isteğe bağlı bir doFullSerialization parametresi alır. Bu referans durumunun farklı bir grup tarafından serileştirilmiş serileştirici (ör. yedekleme veri modelleri). Bu parametre, referans verilen durum, blok seri durumdan çıkarıldığında kullanılamaz. Bu nedenle bloğunun kendisini serileştirmesi gerekir. Örneğin bu, tek bir blok serileştirildiğinde veya bir blok kopyalanıp yapıştırıldığında true değerini alır.

Bunun için yaygın olarak kullanılan iki kullanım alanı şunlardır:

  • Tek bir blok, yedekleme verilerinin tamamlandığı bir çalışma alanına yüklendiğinde yoksa modelin kendi durumunda olması gerekene kadar veri modeli oluşturabilirsiniz.
  • Bir blok kopyalanıp yapıştırıldığında her zaman yeni bir destek oluşturulur veri modelini kullanır.

Bunu kullanan bazı bloklar @blockly/block-shareable-procedures blokları. Normalde durumunu depolayan yedekleme veri modeline bir referansı serileştirirler. Ancak doFullSerialization parametresi doğru ise tüm durumu. Paylaşılabilir prosedür blokları, bu işlemi uygulayarak bir başvuru referansı yerine yeni bir yedekleme veri modeli kullanabilirsiniz.

mutationToDom ve domToMutation

mutationToDom ve domToMutation, aşağıdakilerle çalışan serileştirme kancalarıdır: XML serileştirme sistemini kullanmanız gerekir. Bu kancaları yalnızca gerektiğinde kullanın (ör. eski bir kod tabanı üzerinde çalışıyorsanız) saveExtraState ve loadExtraState.

mutationToDom, blok ve domToMutation aynı XML düğümünü kabul eder ve durumu engelleyebilirsiniz.

// 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_();
},

Elde edilen XML aşağıdaki gibi görünür:

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

mutationToDom fonksiyonunuz null döndürürse fazladan hiçbir öğe XML'e eklenir.

Kullanıcı Arayüzü Kancaları

Mutatörünüzün bir parçası olarak belirli işlevler sağlarsanız Blockly, varsayılan "mutator" Kullanıcı arayüzünüz.

Fazladan serileştirme eklemek istiyorsanız bu kullanıcı arayüzünü kullanmanız gerekmez. Yapabilecekleriniz blocks-plus-eksi" gibi özel bir kullanıcı arayüzü kullanın eklenti ya da hiç kullanıcı arayüzü kullanamazsınız.

ayrıştırma ve ayrıştırma

Varsayılan kullanıcı arayüzü, compose ve decompose işlevlerini kullanır.

decompose "patlıyor" daha küçük alt bloklara bölünebilir. eklenip silindi. Bu işlev bir "üst blok" döndürmelidir yani mutator çalışma alanındaki alt blokların bağlandığı ana bloka

compose daha sonra alt blokların yapılandırmasını yorumlar ve bunları kullanarak ana bloğu değiştirebilirsiniz. Bu işlev "üst blok"u kabul etmelidir ki bu da şuydu: decompose tarafından parametre olarak döndürülür.

Bu işlevlerin "karma" hâline geleceğini unutmayın "değişen" bloka yani this bu bloku ifade etmek için kullanılabilir.

// 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

İsterseniz, aynı zamanda ile çalışan bir saveConnections varsayılan kullanıcı arayüzünü kullanın. Bu işlev, sitenizin alt öğelerini ilişkilendirme içinde bulunan alt bloklara sahip ana blok (ana çalışma alanında bulunur) çalışma alanınız. Bu verileri kullanarak compose ana bloğun alt öğelerini tekrar bağlar. alt bloklar yeniden düzenlenir.

saveConnections, "üst bloku" kabul etmelidir decompose cihazınız tarafından iade edildi işlevini parametre olarak kabul eder. saveConnections işlevi tanımlıysa Blockly compose numaralı telefonu aramadan önce arayacak.

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();
  }
},

Kaydettiriliyor

Mutatörler yalnızca özel bir uzantı türüdür, bu nedenle iyi olmaları blok türünüzün JSON'sinde kullanabilmeniz için öncelikle kayıtlı olan tanımı.

// 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'da kullanabilmeniz için mutatörle ilişkilendirilecek dize.
  • mixinObj: Çeşitli mutasyon yöntemlerini içeren bir nesne. Ör. saveExtraState ve loadExtraState.
  • opt_helperFn: Şu işlemleri gerçekleştirecek isteğe bağlı bir yardımcı işlev: Karışım karıştırıldıktan sonra blokta çalıştırılır.
  • opt_blockList: Oluşturulacak isteğe bağlı blok türleri (dize olarak) kullanıcı arayüzü yöntemleri de tanımlanmıştır.

Uzantıların aksine, her engelleme türünün yalnızca bir mutatörü olabileceğini unutmayın.

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

Yardımcı işlev

Mixin ile birlikte bir mutatör de yardımcı bir işlev kaydedebilir. Bu işlev oluşturulduktan sonra belirli bir türdeki her blokta çalışır ve mixinObj eklendi. Bir mutasyona ilave tetikleyici veya efektler eklemek için kullanılabilir.

Örneğin, liste benzeri blokunuza öğelerin ilk sayısı:

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