Komponenta nemůže nalézt presenter

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

Vyrobil sem si komponentu: app/components/UsersTable.php

namespace Evidence;
use Nette;

class UsersTable extends Nette\Application\UI\Control
{
	private $uzivatel;

    public function __construct(Nette\Object $uzivatel)
    {
        parent::__construct(); // vždy je potřeba volat rodičovský konstruktor
		$this->uzivatel = $uzivatel;
    }

    public function render()
    {
        $this->template->setFile(__DIR__ . '/UsersTable.latte');
        $this->template->users = $this->uzivatel->findAll();
        $this->template->render();
    }
}

a v Presenteru (app/presenters/AdminPresenter.php) si ji volám takto:

	protected function createComponentUsersTable() {
		return new Evidence\UsersTable($this->uzivatel);
	}

Ale problém je v tom, že komponenta nějak nemůže nalézt presenter, na který chci z komponenty odkazovat:

<a n:href="Admin:edit $user->id">editovat</a>

mi vyhazuje: Component with name ‚Admin‘ does not exist.

Nevíte někdo co mám špatně?

Aurielle
Člen | 1281
+
0
-

Tady bude chyba jinde (ale je možné, že přepisování konstruktoru je stále problém, netuším, s Nette jsem už nějakou chvíli nepracoval). Makro n:href je ekvivalentem makra {link}, což znamená, že se v komponentě chová jinak než v presenteru. Pokud chceš odkazovat na presentery v komponentě, musíš to udělat přes klasický {plink}, jinak se snažíš volat jinou komponentu (viz chyba).

22
Člen | 1478
+
0
-

@pidiclovek: ten tvůj příklad konstruktoru bych asi smazal, jeho konstruktor je imho v pořádku, protože rodič má default hodnoty pro $parent, $name NULL, viz. API

@gmvasek má pravdu, {plink} odkazuje na presenter

duke
Člen | 650
+
0
-

gmvasek napsal(a):

…, musíš to udělat přes klasický {plink}, jinak se snažíš volat jinou komponentu (viz chyba).

Přesněji řečeno: Jinak se snažíš odkazovat na subkomponentu tvé komponenty. A protože tvá komponenta žádnou subkomponentu Admin nemá, končí to chybou.

pidiclovek
Člen | 91
+
0
-

Máte samozřejmě pravdu, příště budu pozorněji číst dotaz. Odpověď jsem proto smazal zcela. Omlouvám se za zmatení

Nich
Člen | 49
+
0
-

S {plink} už to frčí, moc děkuji za pomoc

josef.sabl
Člen | 153
+
0
-

Zdravíčko.

Mám stejný problém, jako Nich. Nicméně po nahrazení n:href za plink mi laděnka hlásí Call to a member function link() on a non-object. Má to na svědomí registrace překladače. Když řádek se setTranslator zakomentuju, vše funguje, až na podtržítkové makro.

Co dělám špatně? Díky.

Třída controly:

class BcLineControl extends \Nette\Application\UI\Control
{
	public function __construct($translator)
	{
		parent::__construct();
		$this->template->setTranslator($translator);
	}

	public function render($bc)
	{
		$template = $this->template;
		$template->setFile(__DIR__ . '/BcLineControl.latte');
		$template->bc = $bc;
		$template->render();
	}
}

Zjednodušená šablona:

<a href="{plink Bc:view $bc->id}">{$bc->id}</a>

Použití v presenteru:

public function createComponentBcLine()
{
	return new bcLineControl($this->context->translator);
}
studna
Člen | 181
+
0
-

Když sáhneš na šablonu v konstruktoru (před připojením k presenteru – attached), tak se ti vytvoří bez presenteru. Přesuň to do render a bude to fungovat. :)

Editoval studna (23. 10. 2012 19:01)

josef.sabl
Člen | 153
+
0
-

Díky Ti, upraveno na viz. níže a funguje. Ale intuitivní to zrovna není, řekl bych taková gotcha :-)

class BcLineControl extends \Nette\Application\UI\Control
{
    private $translator;

    public function __construct($translator)
    {
        parent::__construct();
        $this->translator = $translator;
    }

    public function render($bc)
    {
        $template = $this->template;
        $template->setFile(__DIR__ . '/BcLineControl.latte');
        $template->setTranslator($this->translator);
        $template->bc = $bc;
        $template->render();
    }
}

Editoval josef.sabl (24. 10. 2012 9:55)

josef.sabl
Člen | 153
+
0
-

Tak ještě stručnější verze :-)

class BcLineControl extends \Nette\Application\UI\Control
{
	public function render($bc)
	{
		$template = $this->template;
		$template->setFile(__DIR__ . '/BcLineControl.latte');
		Mafra\Helpers::RegisterAll($template);
		$template->setTranslator($this->getPresenter()->context->translator);

		$template->bc = $bc;

		$template->render();
	}
}
Arynev
Člen | 33
+
0
-

Co zkusit

protected function createTemplate($class = NULL){

	$template = parent::createTemplate($class);
	$template->setFile(__DIR__ . '/BcLineControl.latte');
        Mafra\Helpers::RegisterAll($template);
        $template->setTranslator($this->translator);

	return $template;

}

a mít metodu render čistou? Ale translator si určitě předávej z venku v konstruktoru nebo setteru.