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.