Dynamicka tvorba komponent v komponente
Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.

- pjoter
 - Člen | 118
 
Zdravim,
resim problem takovy problem: mam komponentu productsList, ve ktere nacitam
z databaze produkty a rendruju jejich vypis. Problem je v tom ze potrebuju ke
kazdemu produktu vytvorit formular pro nakup produktu. Z zivotniho cyklu
presenteru, predpokladam ze v komponente to bude stejne a tedy v renedru uz je
pozde na pripojeni podkomponent.
Ukazka kodu komponenty:
<?php
class ProductsList extends Control {
    private $node,$orderBy,$orderHow,$view;
    function __construct($node,$orderBy,$orderHow,$view)
    {
         $this->node = $node;
         $this->orderBy = $orderBy;
         $this->orderHow = $orderHow;
         $this->view = $view;
    }
    public function render()
    {
        $template = $this->createTemplate()
                    ->setFile(dirname(__FILE__) . "/ProductsList.latte");
        $this->getPresenter()->models->Nodes->setProductNodes($this->node);
        $paginator = $this['paginator']->getPaginator();
        $paginator->itemCount = count($this->getPresenter()->models->Nodes->findProducts()->fetchAll());
        $products = $this->getPresenter()->models->Nodes->findProducts($this->orderBy,$this->orderHow)->fetchAll($paginator->offset, $paginator->itemsPerPage);
        foreach($products as $p)
        {
            $this->createAddToBasketForm($p);
        }
        $template->products = $products;
        $template->view = $this->view;
        $template->render();
    }
   protected function createAddToBasketForm($product)
    {
            $form = new \Nette\Application\UI\Form($this, 'product' . $product->ProductID);
            $form->addHidden('ProductID', $product->ProductID);
            if($product->StepAmount == "0")
                $product->StepAmount = 1;
            $values = array();
            for($i=$product->MinAmount;$i<=($product->MinAmount*10);$i+=$product->StepAmount)
            {
                $values[$i] = $i;
            }
            $form->addSelect('amount', 'ks',$values);
            $form->addImage('add',$this->template->basePath.'/images/shop/btn-buy.png', 'Vložit do košíku');
            $form->onSuccess[] = callback($this, 'basketFormSubmitted');
            return $form;
    }
    public function basketFormSubmitted(\Nette\Application\UI\Form $form)
    {
            $values = $form->getValues();
            $cart = $this->getPresenter()->context->session->getSection('cart');
            if(!isset($cart->items))
                    $cart->items = array();
            $cart->items[$values['ProductID']] = $values['amount'];
    }
...
?>
Budu rad za jakykoli tip ci pomoc.
Editoval pjoter (13. 10. 2011 20:56)

- Filip Procházka
 - Moderator | 4668
 
Co takhle?
class ProductsList extends Control
{
	private $node;
	private $orderBy;
	private $orderHow;
	private $view;
	private $productsList = array();
	public function __construct($node, $orderBy, $orderHow, $view)
	{
		$this->node = $node;
		$this->orderBy = $orderBy;
		$this->orderHow = $orderHow;
		$this->view = $view;
	}
	public function getProducts()
	{
		if (!$this->productsList) {
			$models = $this->getPresenter()->models;
			$nodes = $models->Nodes;
			$nodes->setProductNodes($this->node);
			$paginator = $this['paginator']->getPaginator();
			$paginator->itemCount = count($nodes->findProducts()->fetchAll());
			$products = $nodes->findProducts($this->orderBy, $this->orderHow)
				->fetchAll($paginator->offset, $paginator->itemsPerPage);
			foreach ($products as $product) {
				$this->productsList[$product->ProductID] = $product;
			}
		}
		return $this->productsList;
	}
	public function render()
	{
		$template = $this->createTemplate()
			->setFile(dirname(__FILE__) . "/ProductsList.latte");
		$template->products = $this->getProducts();
		$template->view = $this->view;
		$template->render();
	}
	protected function createComponent($id)
	{
		$product = $this->products[$id];
		// pomoci parametru konstruktoru pripnu komponentu k Presenteru
		$form = new Nette\Application\UI\Form;
		$form->addHidden('ProductID', $product->ProductID);
		$form->addSelect('amount', 'ks', $this->getProductAmounts($product));
		$form->addImage('add', $this->template->basePath . '/images/shop/btn-buy.png', 'Vložit do košíku');
		$form->onSuccess[] = callback($this, 'basketFormSubmitted');
		return $form;
	}
	private function getProductAmounts($product)
	{
		if($product->StepAmount == "0") {
			$product->StepAmount = 1;
		}
		$values = array();
		for($i=$product->MinAmount; $i<=($product->MinAmount*10) ;$i+=$product->StepAmount) {
			$values[$i] = $i;
		}
		return $values;
	}
	public function basketFormSubmitted(\Nette\Application\UI\Form $form)
	{
		$values = $form->getValues();
		$cart = $this->getPresenter()->context->session->getSection('cart');
		if(!isset($cart->items)) {
			$cart->items = array();
		}
		$cart->items[$values['ProductID']] = $values['amount'];
	}
Takto by to mělo být perfektně lazy.
Editoval HosipLan (13. 10. 2011 21:12)