Vykreslení jedné komponenty vícekrát s jinými parametry + AJAX

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

Ahoj,
mám jednu komponentu PollControl, která má signál vote pro hlasování a render metodu přijímající id otázky, která se má vykreslit. Také mám definovaný snippet answers, který mi obaluje všechny odpovědi a který invaliduji při zahlasování (v signálu vote). Všechno funguje krásně až do okamžiku, než chci přidat více anket na jednu stránku.

{control poll, 1}
{control poll, 2}

Zde nastává problém se snippety. Nette bohužel udělí snippetům v obou anketách stejné id, což nemůže z principu fungovat. Existuje způsob, jak z toho ven?

F.Vesely
Člen | 369
+
+1
-

Nepredavej id v render ale v konstruktoru.

CZechBoY
Člen | 3608
+
+1
-

Pouzij multiplier + predani id v konstruktoru.

class PollControl extends Control
{
    public function __construct($id)
    {
        $this->id = $id;
    }
}
interface IPollControlFactory
{
    /**
     * @param int $id
     * @return PollControl
     */
    function create($id);
}

class PollPresenter extends Presenter
{
    /** @var PollControlFactory @inject */
    public $pollFactory;

    protected function createComponentPoll()
    {
        return new Nette\Application\UI\Multiplier(function($id) {
            return $this->pollFactory->create($id);
        });
    }
}
{control poll-$nejakyId}

Editoval CZechBoY (24. 4. 2016 19:28)

SuperMartas
Člen | 13
+
0
-

Super, díky, pomohlo. S tím vyvstává ale další problém, který tu byl už i předtím a nesouvisí až tak s AJAXem. V PollControl se totiž dotazuji databáze na další dodatečná data k anketě, takže logicky s každou další anketou na stránce roste lineárně počet dotazů na databázi. Lze tomu nějak chytře předejít a dostat se tak na konstantní počet dotazů na databázi? Používám Nette\Database.

CZechBoY
Člen | 3608
+
+2
-

Tak můžeš si místo ID předávat nějaký informace o té anketě.

class PollControl extends Control
{
	public function __construct(array $info)
	{
		$this->info = $info;
	}
}
interface IPollControlFactory
{
	/**
	 * @param array $info
	 * @return PollControl
	 */
	function create(array $info);
}

class PollPresenter extends Presenter
{
	/** @var PollFactory @inject */
	public $pollFactory;

	private $pollInfos = [];

	public function actionDefault()
	{
		$this->pollInfos = $this->pollRepository->getAllPaired(); // array [id => info]
	}

	public function renderDefault()
	{
		$this->template->polls = $this->pollInfos;
	}

	protected function createComponentPoll()
	{
		return new Multiplier(function($id) {
			$pollInfo = $this->pollInfos[$id];

			return $this->pollFactory->create($pollInfo);
		});
	}
}
{foreach $polls as $id => $poll}
	<h2>Anketa {$poll->name}</h2>
	{control poll-$id}
{/foreach}

Editoval CZechBoY (24. 4. 2016 19:27)

SuperMartas
Člen | 13
+
0
-

Super, díky, už se mi něco rodí v hlavě. ;)

Kcko
Člen | 468
+
+1
-

Jen, že do toho vstupuji, jelikož je to komponenta ankety, která může být na různých místech po celém webu, tj. ne jen v PollPresenteru, nebylo by lepší to kešování a dotazy na data zařídít přímo v komponentě?