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
+
0
-

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
+
0
-

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)

pjoter
Člen | 118
+
0
-

Diky za nasmerovani a i za tipy co jak delat pekneji :). Zitra to vyzkousim, jinak createComponent() je schvalne bez nazvu? A ty formulare vykreslim v sablone pomoci {control cartForm $product->ProductID} ?

Jan Endel
Člen | 1016
+
0
-

Zápisy createComponentName() a createComponent($name) jsou ekvivalentní, pokud chápu hosipLanovy kódy dobře, měly by se vykreslovat pomocí {control $product->ProductID}