Method ProductPresenter::createComponentProductExtracted() did not return or create the desired component

- svobodai
 - Člen | 136
 
Co s touhle chybou.
Část Presenteru
class ProductPresenter extends BasePresenter
{
	protected function createComponentProductExtracted()
	{
		$vars = $this->request->getParameters();
		$dataSelection = $this->context->createProductExctractData();
		$dataSelection->where(array('productFoundURLId'=>$vars['id']));
		$product = $dataSelection->fetch();
		$template = $this->createTemplate();
		$template->setFile(__DIR__ . '/../templates/Product/product.latte');
		$template->product = $product;
		return $template;
	}
}
Jedná se o načtení detailu produktu. v proměnné produkt je pole načtené z DB a data tam jsou.
šablona product.latte
<div name="FoundExpandData">
	{$product->productName}
	{$product->productName}
	{'images/products/'.$product->imageLocation|image}
	{$product->description}
	{$product->brandName}
	{$product->priceRegular}
	{$product->priceOnWebSite}
	{$product->UPC}
	{$product->skuOnWebSite}
	{$product->productDimension}
	{$product->suggestedUse}
	{$product->supplementFacts}
	{$product->warning}
	{$product->ingredientsActive}
	{$product->ingredientsInactive}
	{$product->dietaryConsideration}
	{$product->deliveryFormats}
	{$product->intendedUsers}
	{$product->dosage}
	{$product->precautions}
	{$product->discontinuedDateTime}
	{$product->brandWebSite}
</div>
šablona presenteru
{block content}
<h1>Products details</h1>
{widget productExtracted}
{/block}
Těch komponent je tam reálně více, ale s nimi není problém, ty se zobrazují korektně.

- uestla
 - Backer | 799
 
Hláška zní jasně – v metodě nevracíš instanci
UI\IControl, ale evidentně instanci šablony.
Čili řešením je vytvoření komponenty:
ProductControl.php
class ProductControl extends Nette\Application\UI\Control
{
	private $product;
	function setProduct($product) { $this->product = $product; return $this; }
	function render() {
		$this->template->setFile(__DIR__ . '/ProductControl.latte');
		$this->template->product = $this->product;
		$this->template->render();
	}
}
ProductControl.latte – ve stejné složce jako komponenta
<div name="FoundExpandData">
        {$product->productName}
        {$product->productName}
        {'images/products/'.$product->imageLocation|image}
        {$product->description}
        {$product->brandName}
        {$product->priceRegular}
        {$product->priceOnWebSite}
        {$product->UPC}
        {$product->skuOnWebSite}
        {$product->productDimension}
        {$product->suggestedUse}
        {$product->supplementFacts}
        {$product->warning}
        {$product->ingredientsActive}
        {$product->ingredientsInactive}
        {$product->dietaryConsideration}
        {$product->deliveryFormats}
        {$product->intendedUsers}
        {$product->dosage}
        {$product->precautions}
        {$product->discontinuedDateTime}
        {$product->brandWebSite}
</div>
A nakonec v presenteru:
class ProductPresenter extends BasePresenter
{
        protected function createComponentProductExtracted()
        {
		$product = $this->context->createProductExctractData()
			->where('productFoundURLId', $this->params['id'])
			->fetch();
		if (!$product) throw ...;
		$c = new ProductControl();
		$c->setProduct($product);
		return $c;
        }
}
A šablona presenteru:
{block content}
<h1>Products details</h1>
{control productExtracted} {* raději "control" než "widget" - ten je totiž deprecated *}
{/block}
				
- uestla
 - Backer | 799
 
když v té komponentě mám odkazy
Myslíš v šabloně komponenty?
Pokud ano, logicky by odkaz neměl směřovat na komponentu, ale na
nadřazenou jednotku, která všechny ty komponenty (které chceš podle
parametrů odkazu změnit) vytváří a vykresluje – v tomhle případě
tedy na presenter (makro {plink ...}).
V něm bych si zavedl pomocnou proměnnou, kterou bych odkazem nastavoval, a při vytváření komponenty bych její hodnotu komponentě předal (opět setterem jako product). Komponenta by se na základě hodnoty této předané proměnné nějak zachovala.