Vložení komponenty presenteru z šablony komponenty

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

Zdravím,

tak se na Vás musím zase obrátit, už si nějak nevím rady.

Má situace:

  • vytvořil jsem komponentu Tab , které se předají pole s identifikátory záložek array(název, popis)
  • podle názvů záložek si sestaví cestu k šablonám
  • v šabloně pohledu presenteru volám tu komponentu Tab (např. {control detailTabs})
  • ta komponenta má vlastní šablonu tab.latte ve adresáři s komponentami
  • v té šabloně komponenty postupně includuji šablony pro každou záložku
  • problém nastane tehdy, když chci volat komponentu vytvořenou v presenteru z šablony té záložky

Nevíte jak to udělat? Nebo Vás napadá lepší řešení?

Šaman
Člen | 2666
+
0
-

Sorry, maličko se v tom ztrácím..
Ale jestli Tab je komponenta a záložky jsou includované do té komponenty, tak myslím, že záložky by měly být také komponenty.

Jestli chceš vkládat do komponenty nějakou další komponentu, musíš si ji buď vytvořit explicitně (vytvořit pro ni továtničku v komponentě), nebo upravit implicitní createComponent($name).

dibalaj
Člen | 40
+
0
-

Já vím, přemýšlím nad tím dnes celý den.
Lepší řešení mě jaksi nenapadlo.

Potřebuji udělat nějakou komponentu, která by mi umožnila vytvořit záložky s JS přepínáním.
Dříve (ve vlastním frameworku) jsem to měl tak, že každá záložka měla svou „renderovací“ metodu tabněco() a v nich jsem vytvářel obsah záložek (ten se pak zachytával pomocí OB a vkládal do záložek).

Když už jsem přešel na Nette :-), tak bych chtěl využít dokonalosti šablonovacího systému, a za boha mě nenapadá řešení, které by mi to umožnilo.

Mít pro každou záložku továrničku je podle mě „kravina“, jelikož budu mít hodně stránek, kde záložky budou, nebudu do komponenty připisovat továrničky.

Jak jsi to myslel s tou úpravou implicitního createComponent($name)?

Filip Procházka
Moderator | 4668
+
0
-

Nesouhlasím, měl bys mít komponenty pro jednotlivé záložky. Ale nemusí být nutně v tvé komponentě, co ty záložky vykresluje. Co takhle?

protected function createComponentSomethingTabs()
{
	$tabs = new TabsControl;
	$tabs->addTab($this, 'fooTab'); // rodič a jméno komponenty
	$tabs->addTab($this, 'barTab');
	return $tabs;
}

protected function createComponentFooTab()
{
	return new FooControl;
}

protected function createComponentBarTab()
{
	return new BarControl;
}

komponenta

class TabsControl extends Nette\Application\UI\Control
{
	private $tabs = array();

	public function addTab(Nette\ComponentModel\IContainer $parent, $componentName, $title = NULL)
	{
		$this->tabs[] = array(
			'component' => $parent->getComponent($componentName),
			'title' => $title
		);
	}

	public function render()
	{
		$this->template->tabs = $this->tabs;
		$this->template->render();
	}
}

vykreslení

{foreach $tabs as $tab}
	<h2 class="title">{$tab['title']}</h2>
	<div class="tab">{control $tab['component']}</div>
{/foreach}

Editoval HosipLan (5. 8. 2012 16:10)

Šaman
Člen | 2666
+
0
-

V createComponent($name) se dá univerzálně vytvořit komponenta podle parametru $name. Když máš požadavek na komponentu FooBar (třeba protože ji voláš v šabloně), tak se hledá metoda createComponentFooBar() a pokud se nenajde, tak se zavolá createComponent('fooBar'), která implicitně nic nedělá. No a tuhle metodu si můžeš přepsat tak, aby to třeba vytvořilo instanci třídy FooBar a vrátilo ti ji. Nebo zkrátka cokoliv bys měl v továrničce.

dibalaj
Člen | 40
+
0
-

@HosipLan:
Díky za tvůj příklad,

a ano, takhle by to šlo, pokud bych chtěl vykreslovat například formulář na jedné záložce, další komponenta na druhé záložce, atp.
Nevím, zda se mýlím (Nette používám pár týdnů), ale co když budu chtít na jedné záložce vykreslit samotnou tabulku?

Dám příklad, budu mít stránku s detailem uživatele, pak záložky „detail“ a „tools“.

V záložce „detail“ budu chtít mít pár tabulek s informacemi o uživateli, v „tools“ pak nějaké formuláře pro změnu hesla apod.

Jak to udělám, aby každá ta záložka mohla mít nadefinovaný obsah v nějaké šabloně?

Editoval dibalaj (5. 8. 2012 16:23)

Filip Procházka
Moderator | 4668
+
0
-

Ta záložka bude obsahovat komponentu. Ta komponenta bude mít vlastní šablonu. Do komponenty předáš data a komponenta je vykreslí.

dibalaj
Člen | 40
+
0
-

HosipLan napsal(a):

Ta záložka bude obsahovat komponentu. Ta komponenta bude mít vlastní šablonu. Do komponenty předáš data a komponenta je vykreslí.

Díky :-) vyřešil jsem to jinak, na straně Javascriptu.

Měl bych ale ještě jeden dotaz. Narazil jsem na další problém – s formulářem.

Mám jednoduchý formulář:

<?php
  protected function createComponentDetailForm()
  {
    $form = new \Nette\Forms\Form();

    $form->addText('name', 'Jméno:', 30)
         ->setRequired('Jméno uživatele je povinná položka!');

    $form->addText('login', 'Login:', 30)
         ->setRequired('Login uživatele je povinná položka!')
         ->addRule(\Nette\Forms\Form::MIN_LENGTH, 'Login musí mít alespoň %d znaků', 5);

    $form->addCheckbox('admin', 'administrátorský účet');
    $form->addSubmit('submit', 'Uložit');

    $form->onSuccess[] = callback($this, 'detailFormSubmitted');

    return $form;
  }


  public function detailFormSubmitted(\Nette\Application\UI\Form $form)
  {
    dump($form);
    exit;
  }
?>

při kliknutí na SubmitButton se nejspíše formulář odešle, jelikož POST data se pak odesílají znovu a znovu, ale nedojde k volání metody detailFormSubmitted(). Nenapadá Vás proč? Mám něco špatně?

Filip Procházka
Moderator | 4668
+
0
-

Ano máš. Použij Nette\Application\UI\Form, nikoliv Nette\Forms\Form.

dibalaj
Člen | 40
+
0
-

Díky ! Ještě že to fórum existuje :) Nette se mi opravdu líbí :)