Engelleme tanımlarını değiştirme

Sık sorulan sorulardan biri, mevcut bir bloğun tanımını nasıl değiştireceğinizdir. Örneğin, bağlantı kontrolü eklemek veya bir alanı değer girişi olarak değiştirmek isteyebilirsiniz.

Genel olarak, bir blok tanımını yerinde değiştirmek mümkün değildir.

Mevcut bir tanımı değiştirme

Mevcut bir blok türünün tanımını değiştirmek istiyorsanız:

  1. Blok kod oluşturucular dahil olmak üzere mevcut tanımın bir kopyasını oluşturun.
  2. Kopyayı değiştirin ve türünüze yeni bir ad verin.
  3. Yeni tanımınızı Blockly.Blocks'e ekleyin.

Mevcut bir tanımı neden doğrudan değiştiremiyorum?

Mevcut bir tanımı neden değiştiremediğinizi merak ediyorsanız okumaya devam edin. Bazı olasılıkları değerlendireceğiz.

Mevcut bir tanımı doğrudan değiştirme

Mevcut bir bloğun tanımını doğrudan değiştirmenin iki yolu vardır: kodda monkeypatching ve kod çatallama. Her iki yöntem de, monkeypatched veya çatallanmış koda bağlı kodu bozma riski taşıdığı için kesinlikle önerilmez. Her iki teknik de güncellemeleri ve hata düzeltmelerini entegre etmeyi zorlaştırır. Daha fazla bilgi için Monkeypatching hakkında ve Fork Blockly başlıklı makaleleri inceleyin.

Mevcut bir tanımın alt sınıfını oluşturma

Mevcut bir tanımı bir şekilde alt sınıfa ayırmak isteyebilirsiniz. Maalesef bu mümkün değildir. Çünkü blok tanımları sınıf değil, karma sınıftır. Örneğin, tanımda renk özelliği olmadığı için bir renk özelliğinin üzerine yazılma imkanı yoktur. Bunun yerine, bloktaki renk özelliğini ayarlamak için setColour işlevini çağıran bir init işlevi vardır. Çağrı init içinde olduğundan init işlevinin tamamını değiştirmeden çağrıyı değiştirmenin bir yolu yoktur.

Mevcut bir tanımdaki işlevin üzerine yazma

Mevcut bir tanımdaki işlevin üzerine yazılabilir:

Blockly.Blocks['existing_block'].init = function() {/*new function*/};

Bu yöntem işe yarar ancak mevcut işlevi kopyalayıp değiştirmeniz gerekir. Tek bir satırı sihirli bir şekilde değiştiremezsiniz. Bununla ilgili birkaç sorun vardır:

  • Bu, tanımın tamamını kopyalayıp değiştirmekten çok farklı değildir.
  • Blockly'nin yerleşik blokları gibi JSON'da tanımlanan blokların init işlevini değiştirmek için kullanamazsınız. Bunun nedeni, kopyalanacak bir init işlevi olmamasıdır. Bu işlev, çalışma zamanında oluşturulur.
  • Bu yöntem, JavaScript kullanarak blokunuzu tanımlamanızı gerektirir. Bu da yerelleştirmeyle ilgili sorunlara yol açabilir.

init sonuçlarını geçersiz kılma

Bir init işlevinin "yalnızca bir satırını değiştirmenin" bir yolu, init işlevini orijinal init işlevini çağıran ve ardından bu aramanın sonucunun üzerine yazan bir işlevle değiştirmektir. Örneğin, aşağıdaki kod logic_null bloğunun rengini değiştirir:

const originalInit = Blockly.Blocks['logic_null'].init;
Blockly.Blocks['logic_null'].init = function() {
  originalInit.call(this);
  this.setColour(300);
}

Maalesef bu, göründüğünden daha az faydalıdır. Örneğin:

  • Bağlantı kontrollerini genişletmek veya daha az kısıtlayıcı bir alan doğrulayıcı uygulamak, blok kodu oluşturucular ve etkinlik işleyiciler tarafından yapılan varsayımları geçersiz kılabilir.

  • Bir alanı değer girişiyle değiştirmek, blok kodu oluşturucuları ve alan doğrulayıcıları ile etkinlik işleyicileri bozar. Ayrıca, farklı yerel ayarlar farklı giriş ve alan türleri ve sıraları olan bloklara neden olabileceğinden, yerelleştirilmiş bloklar için bunu yapmak son derece zor olabilir.

JSON tanımında bir anahtar/değer çiftinin üzerine yazma

Bir bloğun JSON'u herkese açıksa JSON değerlerinin tek tek üzerine yazılabilir. Örneğin:

// Block definition.
blockJson = {...};
Blockly.Blocks['my_block'] = {
  init: function() {
    initJson(blockJson); // Called when the block is created.
  }
}

// Third-party code.
blockJson.colour = 100;

Ancak bu yöntem yalnızca JSON nesnesi herkese açıksa, tanım init işlevini açıkça tanıyorsa ve init işlevi initJson'u çağırıyorsa çalışır. JSON, üçüncü tarafların değiştirme şansı bulamadan önce işlendiği için JSON, defineBlocksWithJsonArray veya createBlockDefinitionsFromJsonArray'e iletilirse çalışmaz. (Blockly'nin yerleşik bloklarının createBlockDefinitionsFromJsonArray kullandığını unutmayın.)

Peki JSON bu şekilde tanımlanmamışsa ne olur? JSON özelliklerinin üzerine yazma işlemi hâlâ mümkün değil mi? Maalesef hayır. Tanım bir init işlevi (JSON değil) içerir ve init işlevini JSON'a dönüştüren bir işlev yoktur.

// Doesn't work. There is no getJson() function.
const json = Blockly.Blocks['existing_block'].getJson();
json['message0'] = 'my new message0';
Blockly.Blocks['existing_block'].init = function () {
  initJson(json);
};

Yeniden kullanıma uygun tasarımlar

Kendi özel bloklarınızı tasarlarken bunları yeniden kullanımı teşvik edecek şekilde tasarlayabilirsiniz.

JSON'u yeniden kullanma

Büyük ölçüde benzer iki bloğunuz varsa bir üst JSON tanımı oluşturabilir ve bunu alt tanımlarda yeniden kullanabilirsiniz. Örneğin:

const parentJson = {
  // shared properties
};

Blockly.Blocks['child_block_1'] = {
  init: function() {
    initJson({...parentJson, colour: 100})
  }
}

Blockly.Blocks['child_block_2'] = {
  init: function() {
    initJson({...parentJson, colour: 200})
  }
}

Diğer bir alternatif de JSON'unuzu herkese açık bir nesnede tanımlamak ve bu nesneyi init işlevinizde initJson parametresine iletmektir. Bu sayede diğer kullanıcılar, tek tek mülklerin üzerine yazabilir. Daha fazla bilgi için JSON tanımında bir anahtar/değer çiftinin üzerine yazma başlıklı makaleyi inceleyin.

İşlevleri yeniden kullanma

Bloklar, blok düzeyinde etkinlik işleyiciler, özel ipuçları, alan doğrulayıcılar ve değiştiriciler tarafından kullanılan işlevler gibi bir dizi standart işlev tanımlayabilir. Ayrıca, bir robot kolunun mevcut konumu gibi harici verilerden alan değerlerini ayarlayan bir işlev gibi özel davranış sağlayan işlevler de tanımlayabilir.

Bu işlevleri bloklar arasında yeniden kullanabilirsiniz.

Açılır liste alanı kullanma

Bir operatör dışında büyük ölçüde aynı olan bir blok grubunuz varsa operatör için açılır liste alanı içeren tek bir blok tasarlayabilirsiniz. Örneğin:

  • Yerleşik logic_operation bloğu, and ve or operatörlerini içeren bir açılır liste kullanır.
  • Yerleşik math_arithmetic bloğu, +, -, ×, ÷ ve ^ operatörlerini içeren bir açılır menü kullanır.

Bu tür bloklar için kod oluşturucular yazmak genellikle biraz daha karmaşıktır ancak yine de birden fazla blok yazıp yönetmekten daha kolaydır.

Değiştirici kullanma

Aynı programlama yapısının farklı varyasyonlarını temsil eden bir blok kümeniz varsa değişken kullanan tek bir blok oluşturabilirsiniz. Örneğin, yerleşik controls_if bloğu, if-then-else ifadelerinin birden fazla varyasyonunu temsil edebilir.