Call to a member function render() on a non-object

- weckho
 - Člen | 94
 
Ahoj,
přejmenoval jsem si DefaultPresenter.php na HomePresenter.php (strašně mě to mátlo > Default x Base). V HomePresenteru mám metodu „protected function createComponent($name)“, kterou jsem převzal z příkladu CD-collection v examples. Metoda mi vytvoří formulář pro přihlášení. Když se presenter jmenoval DefaultPresenter.php, tak vše jelo, nyní (po přejmenování) šablona hlásí chybu:
Call to a member function render() on a non-object
Jde o řádek v šabloně:
<tr><td><?php echo TemplateHelpers::escapeHtml($form->render('begin')) ?></td><td></td></tr>
Chybě rozumím, nevím ale jak ji napravit.. Děkuji za každou radu.

- weckho
 - Člen | 94
 
Ahoj,
myslím, že nezapomněl, tady je zdroják presentru:
<?php
require_once dirname(__FILE__) . '/BasePresenter.php';
class HomePresenter extends BasePresenter
{
	/** @persistent */
	public $backlink = '';
	public static function getPersistentParams()
	{
		return array('backlink');
	}
	/********************* component factories *********************/
	/**
	 * Login form component factory.
	 * @return mixed
	 */
	protected function createComponent($name)
	{
		switch ($name) {
			case 'LoginForm':
				$form = new AppForm($this, $name);
				$form->addText('username', 'Email:')
				->addRule(Form::FILLED, 'Vyplňte prosím emailovou adresu.');
				$form->addPassword('password', 'Heslo:')
				->addRule(Form::FILLED, 'Vyplňte prosím heslo.');
				$form->addSubmit('login', 'Přihlásit se');
				$form->addProtection('Please submit this form again (security token has expired).');
				$form->onSubmit[] = array($this, 'loginFormSubmitted');
				return $form;
			default:
        		parent::createComponent($name);
        }
	}
	public function loginFormSubmitted($form)
	{
		try {
			$user = Environment::getUser();
			$user->authenticate($form['username']->getValue(), $form['password']->getValue());
			$this->getApplication()->restoreRequest($this->backlink);
			$this->redirect('Home:');
		} catch (AuthenticationException $e) {
			$form->addError($e->getMessage());
		}
	}
	public function renderHome()
	{
		$this->template->form = $this->getComponent('LoginForm'); //v nejnovější revizi by mělo fungovat i $this['jmenoformu']
	}
}
A tady daný kousek šablony:
<table>
	<tr><td>{$form->render('begin')}</td><td></td></tr>
	<tr><td><img src="images/icons/mail.png" alt="email" class="icon"> Email:</td><td>{!$form['username']->control}</td></tr>
	<tr><td><img src="images/icons/key.png" alt="pass" class="icon"> Heslo:</td><td>{!$form['password']->control}</td></tr>
	<tr><td></td><td>{!$form['login']->control}</td></tr>
	<tr><td>{$form->render('end')}</td><td></td></tr>
</table>
Díky moc!

- buff
 - Člen | 63
 
Ať se dívám, jak se dívám, chybu nevidím.
Zrekonstruoval jsem minimum, které by mělo vracet stejnou chybu:
HomePresenter.php:
<?php
class HomePresenter extends Presenter {
        public function createComponent($name) {
                switch ($name) {
                case 'LoginForm':
                        $form = new AppForm($this, $name);
                        $form->addText('username', 'Email:')
                                ->addRule(Form::FILLED, 'Vyplňte prosím emailovou adresu.');
                        $form->addPassword('password', 'Heslo:')
                                ->addRule(Form::FILLED, 'Vyplňte prosím heslo.');
                        $form->addSubmit('login', 'Přihlásit se');
                        $form->addProtection('Please submit this form again (security token has expired).');
                        $form->onSubmit[] = array($this, 'loginFormSubmitted');
                        return $form;
                default:
                        parent::createComponent($name);
                }
        }
        public function renderHome() {
                $this->template->form = $this->getComponent('LoginForm');
        }
}
?>
Home.home.phtml:
{$form->render('begin')}
A vrací to zcela správně:
<form action="?action=home&do=LoginForm-submit&presenter=Home" method="post" onsubmit="return validateLoginForm(this)">
Chyba je podle mě někde mimo kód, který jsi poslal…

- weckho
 - Člen | 94
 
Jeej, díky! View jsem neměl změněný na Home, bylo to Default.. Jinak k tomu vylepšení postupu > mě to takhle nevyhovuje, protože mám například u těch formulářových políček v šabloně ikonky, což bych mít při navrženém postupu nemohl, nebo ano?
Ještě jednou díky!
Editoval weckho (24. 7. 2009 11:48)

- jasir
 - Člen | 746
 
weckho napsal(a):
Jinak k tomu vylepšení postupu > mě to takhle nevyhovuje, protože mám například u těch formulářových políček v šabloně ikonky, což bych mít při navrženém postupu mít nemohl, nebo ano?
Je to tak, pokud chceš vykreslovat formulář po částech,
widget nepoužiješ. Co ale v šabloně použíť můžeš je
{$control[‚myForm‘]->render(‚begin‘)} atp. Nevím, jestli je to
lepší než přes parametr šablony, ale často se zbavíš metody
render{View}.

- PetrP
 - Člen | 587
 
Je to lepší. Ale spíš bych použil $presenter, než control, i když v tomto kontextu je to to samé, mohlo by to být zavádějící
{$presenter['loginForm']->render('begin')}
V nejnovějších revizích je také možné toto
{control loginForm 'begin'}
(nemam to ještě vyzkoušene, revize co jsem naposlet testoval to má ještě zabugované)
Editoval PetrP (24. 7. 2009 12:49)

- jasir
 - Člen | 746
 
PetrP napsal(a):
Je to lepší. Ale spíš bych použil $presenter, než control, i když v tomto kontextu je to to samé, mohlo by to být zavádějící
{$presenter['loginForm']->render('begin')}
Myslím, že když budeš všude používat $control, který je
v šablonách univerzální,
snadno sa pak vyndá funkčnost z presenteru a vytvoří se komponenta. Ale je
to otázka vkusu.
V nejnovějších revizích je také možné toto
{control loginForm 'begin'}(nemam to ještě vyzkoušene, revize co jsem naposlet testoval to má ještě zabugované)
Tohle sice funguje, ale uděláš s tím jen ‚begin‘ a'end'.
Vykreslování jednotlivých kontrolů stejně musíš
přes {!$form['jmeno']->control}