Nefunkční nákupní košík – komponenta
- miira
- Člen | 13
Zdravím,
momentálně pracuji na svém prvním e-shopu v Nette a narazil jsem na tento
problém.
Košík mám implementován jako vykreslitelnou komponentu (říká se tomu
control, že? :)), která položky košíku drží v v session v poli $items.
Pro přidání zboží do košíku používám následující (zjednodušený)
handler
<?php
public function handleAdd($id, $count) {
$product = $model->getProduct($id);
$product->count = $count;
$session = Environment::getSession(__CLASS__);
$session->items[] = $product;
}
?>
Ve třídě ProductPresenter mám nadefinovaný tento formulář a jeho obslužnou funkci pomocí kterého bych chtěl přidávat zboží do košíku
<?php
protected function createComponent($name) {
switch($name) {
case 'buyForm':
$form = new AppForm($this, $name);
...
$form->onSubmit[] = array($this, 'buyFormSubmitted');
return;
default:
parent::createComponent($name);
return;
}
}
public function buyFormSubmitted(AppForm $form) {
$values = $form->getValues();
$basket->link('add', $values['id'], $values['count']);
}
?>
Bohužel při odeslání formuláře dojde k selhání a Laděnka oznámí Fatal Error: Call to a member function link() on a non-object. Z čehož jsem vydedukoval, že v době odeslání formuláře patrně ještě není vytvořena komponenta košíku, ale příliš tomu nerozumím.
Ještě dodám, že komponentu košíku vytvářím v BasePresenteru, kterého je ProductPresenter potomkem takto
<?php
public function beforeRender() {
...
$this->template->basket = $this->getComponent('basket');
...
}
...
protected function createComponent($name) {
switch ($name) {
...
case 'basket':
$basket = new Basket($this, $name);
$this->addComponent($basket, $name);
return;
...
}
?>
Děkuju za každou radu, už mi to leze na mozek :)
EDIT: Vůbec nevím, jestli je toto řešení správné, pokud ne, tak mne prosím uveďte na správnou cestu :)
Editoval miira (2. 6. 2009 22:13)
- jasir
- Člen | 746
<?php public function buyFormSubmitted(AppForm $form) { $values = $form->getValues(); $basket->link('add', $values['id'], $values['count']); } ?>
- pomocí
$basket->link('add', $values['id'], $values['count']);
se zřejmě pokoušíš vyvolat metodu handleAdd(). Nicméně link() k tomu neslouží,link()
slouží k tvorbě linků. - $basket není definovaná. Potřebuješ komponentu získat
pomocí
getComponent()
Mohlo by to pak vypadat nějak takhle:
<?php
public function buyFormSubmitted(AppForm $form) {
$values = $form->getValues();
$basket = $this->getComponent('basket');
$basket->handleAdd($values['id'], $values['count']);
}
?>
Jinak metody handleXXX() se většinou jmenují příjemci signálů (tedy
linků), čili
malinko čuchám zmatek v této věci, doporučuji si přečíst dokumentaci životního cyklu
presenteru – Signály a subrequesty
A doporučuji přenést formulář do samotné komponenty basket.
Editoval jasir (2. 6. 2009 22:31)
- miira
- Člen | 13
Děkuju, takhle rychlou reakci jsem vážně nečekal :-)
jasir napsal(a):
…malinko čuchám zmatek v této věci…
Zmatek v tom pořád mám – bylo by tedy správným řešením vytvořit v controlu nějakou metodu prepare, která by vykreslila ten nakupovací formulář?
Editoval miira (2. 6. 2009 22:47)
- jasir
- Člen | 746
Nějak takhle, z hlavy & copy paste z tvého kódu:
Basket control:
<?php
class Basket extends Control {
public function createComponent($name) {
switch($name) {
case 'buyForm':
$form = new AppForm($this, $name);
...
$form->onSubmit[] = array($this, 'buyFormSubmitted');
return;
default:
parent::createComponent($name);
return;
}
}
public function buyFormSumitted(AppForm $form)
{
$values = $form->getValues();
$product = $model->getProduct($id);
$product->count = $count;
$session = Environment::getSession(__CLASS__);
$session->items[] = $product;
$this->presenter->redirect('this'); //po submitu vzdy redirect
}
public function render()
{
$template = $this->getTemplate()
$template->form = $this->getComponent('buyForm');
$template->setFile('basket.phtml');
$template->items = Environment::getSession(__CLASS__)->items;
$template->render();
}
}
?>
Basket.phtml:
<?php
{$form}
<h2>Obsah košíku</h2>
{foreach $items as $item}
Položka: {$item}<br>
{/foreach}
?>
Presenter:
<?php
public function renderShop() {
$this->template->basket = $this->getComponent('basket')
}
protected function createComponent($name) {
switch ($name) {
...
case 'basket':
$basket = new Basket($this, $name);
//$this->addComponent($basket, $name); TOTO tam být nemusí :)
return;
default:
parent::createComponent($name)
}
}
?>
shop.phtml
<?php
{$basket->render()}
?>
Editoval jasir (2. 6. 2009 23:06)