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:
- Blok kod oluşturucular dahil olmak üzere mevcut tanımın bir kopyasını oluşturun.
- Kopyayı değiştirin ve türünüze yeni bir ad verin.
- 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 birinit
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
veor
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.