Multiplier: Dinamik Bileşenler
Etkileşimli bileşenlerin dinamik olarak oluşturulması için bir araç
Tipik bir örnekten başlayalım: bir e-ticaret sitesinde ürün listemiz var ve her biri için sepete ürün eklemek için bir form yazdırmak istiyoruz. Olası seçeneklerden biri, tüm listeyi tek bir formla sarmaktır. Ancak, Nette\Application\UI\Multiplier bize çok daha uygun bir yol sunar.
Multiplier, birden fazla bileşen için bir fabrika tanımlamayı kolaylaştırır. İç içe geçmiş bileşenler prensibine göre çalışır – Nette\ComponentModel\Container'dan miras alan her bileşen başka bileşenler içerebilir.
Belgelerdeki bileşen modeli bölümüne veya Honza Tvrdík'in sunumuna bakın.
Multiplier'ın özü, kurucuda iletilen bir geri çağırma (callback) kullanarak yavrularını dinamik olarak oluşturabilen bir ebeveyn konumunda hareket etmesidir. Örneğe bakın:
protected function createComponentShopForm(): Multiplier
{
return new Multiplier(function () {
$form = new Nette\Application\UI\Form;
$form->addInteger('count', 'Ürün sayısı:')
->setRequired();
$form->addSubmit('send', 'Sepete ekle');
return $form;
});
}
Şimdi şablonda her ürün için formu kolayca oluşturabiliriz – ve her biri gerçekten benzersiz bir bileşen olacaktır.
{foreach $items as $item}
<h2>{$item->title}</h2>
{$item->description}
{control "shopForm-$item->id"}
{/foreach}
{control}
etiketinde iletilen argüman şu formatta:
shopForm
bileşenini al- ve ondan
$item->id
yavrusunu al
1. noktasının ilk çağrısında shopForm
henüz mevcut değildir, bu yüzden fabrikası
createComponentShopForm
çağrılır. Alınan bileşen (Multiplier örneği) üzerinde daha sonra belirli formun
fabrikası çağrılır – ki bu, Multiplier'a kurucuda ilettiğimiz anonim fonksiyondur.
Foreach'in bir sonraki yinelemesinde, createComponentShopForm
metodu artık çağrılmaz (bileşen mevcuttur),
ancak farklı bir yavrusunu aradığımız için ($item->id
her yinelemede farklı olacaktır), anonim fonksiyon
tekrar çağrılır ve bize yeni bir form döndürür.
Geriye kalan tek şey, formun sepete gerçekten eklemesi gereken ürünü eklemesini sağlamaktır – şu anda her ürün
için form tamamen aynıdır. Multiplier'ın (ve genel olarak Nette Framework'teki her bileşen fabrikasının) özelliği bize
yardımcı olur, yani her fabrikanın ilk argümanı olarak oluşturulan bileşenin adını almasıdır. Bizim durumumuzda bu
$item->id
olacaktır, ki bu tam olarak ihtiyacımız olan bilgidir. Bu nedenle, form oluşturmayı hafifçe
ayarlamak yeterlidir:
protected function createComponentShopForm(): Multiplier
{
return new Multiplier(function ($itemId) {
$form = new Nette\Application\UI\Form;
$form->addInteger('count', 'Ürün sayısı:')
->setRequired();
$form->addHidden('itemId', $itemId);
$form->addSubmit('send', 'Sepete ekle');
return $form;
});
}