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

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
weckho
Člen | 94
+
0
-

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.

buff
Člen | 63
+
0
-

To se mi nezdá, že by to bylo přejmenováním. Pošli zdroják presenteru a šablony.

buff
Člen | 63
+
0
-

Změnil jsi i název třídy v tom souboru HomePresenter? Nezapomněl jsi někde nezměněné „Default“?

weckho
Člen | 94
+
0
-

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

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&amp;do=LoginForm-submit&amp;presenter=Home" method="post" onsubmit="return validateLoginForm(this)">

Chyba je podle mě někde mimo kód, který jsi poslal…

PetrP
Člen | 587
+
0
-

je view home a ne default? protoze se metoda renderHome pravdepodobne nepousti. zkontroluj routy, a jestli šablona neni default.phtml

PetrP
Člen | 587
+
0
-

Taky jestli používáš verzi 0.9 můžeš postup vylepšit:

Zrušíš $this->template->form
Vytváření komponenty přesuneš do samostatné továrničky: createComponent($name) >> createComponentLoginForm($name)
A v šabloně {control loginForm}

weckho
Člen | 94
+
0
-

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

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

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

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}