Çarpan: Dinamik Bileşenler

Etkileşimli bileşenlerin dinamik olarak oluşturulmasına yönelik bir araç

Tipik bir sorunla başlayalım: bir e-ticaret sitesinde bir ürün listemiz var ve her ürüne bir sepete ekle formuyla eşlik etmek istiyoruz. Bir yol, tüm listeyi tek bir forma sarmaktır. Daha kullanışlı bir yol ise Nette\Application\UI\Multiplier kullanmaktır.

Multiplier, birden fazla bileşen için bir fabrika tanımlamanıza olanak tanır. İç içe geçmiş bileşenler prensibine dayanır – Nette\ComponentModel\Container adresinden miras alınan her bileşen başka bileşenler içerebilir.

Belgelerdeki bileşen modeline bakın.

Çarpan, yapıcıda geçirilen geri çağırmayı kullanarak çocuklarını dinamik olarak oluşturabilen bir üst bileşen olarak konumlanır. Örneğe bakın:

protected function createComponentShopForm(): Multiplier
{
	return new Multiplier(function () {
		$form = new Nette\Application\UI\Form;
		$form->addInteger('amount', 'Amount:')
			->setRequired();
		$form->addSubmit('send', 'Add to cart');
		return $form;
	});
}

Şablonda her ürün için bir form oluşturabiliriz – ve her form gerçekten de benzersiz bir bileşen olacaktır.

{foreach $items as $item}
	<h2>{$item->title}</h2>
	{$item->description}

	{control "shopForm-$item->id"}
{/foreach}

{control} etiketine aktarılan argüman şöyle der:

  1. bir bileşen edinin shopForm
  2. ve çocuğunu döndürür $item->id

İlk 1. çağrısı sırasında shopForm bileşeni henüz mevcut değildir, bu nedenle onu oluşturmak için createComponentShopForm yöntemi çağrılır. Daha sonra Çarpan'a parametre olarak aktarılan anonim bir fonksiyon çağrılır ve bir form oluşturulur.

foreach adresinin sonraki yinelemelerinde createComponentShopForm yöntemi artık çağrılmaz çünkü bileşen zaten mevcuttur. Ancak başka bir çocuğa referans verdiğimiz için ($item->id iterasyonlar arasında değişir), anonim bir fonksiyon tekrar çağrılır ve yeni bir form oluşturulur.

Son olarak, formun sepete gerçekten doğru ürünü eklediğinden emin olmak gerekir çünkü mevcut durumda tüm formlar eşittir ve hangi ürünlere ait olduklarını ayırt edemeyiz. Bunun için Multiplier'ın (ve genel olarak Nette Framework'teki herhangi bir bileşen fabrika yönteminin) her bileşen fabrika yönteminin ilk argüman olarak oluşturulan bileşenin adını alması özelliğini kullanabiliriz. Bizim durumumuzda bu $item->id olacaktır, ki bu tam olarak bireysel ürünleri ayırt etmek için ihtiyacımız olan şeydir. Tek yapmanız gereken formu oluşturmak için kodu değiştirmektir:

protected function createComponentShopForm(): Multiplier
{
	return new Multiplier(function ($itemId) {
		$form = new Nette\Application\UI\Form;
		$form->addInteger('amount', 'Amount:')
			->setRequired();
		$form->addHidden('itemId', $itemId);
		$form->addSubmit('send', 'Add to cart');
		return $form;
	});
}
versiyon: 4.0