Komponenta nenalezena (tovarnicka)

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

Zdravim,
mam problem v BasePresenter mam dve komponenty

<?php
abstract class BasePresenter extends Presenter implements ISignalReceiver {
  protected function createComponentLoginForm()
	{
	.....
	}

  protected function createComponentInsertForm()
	{
	.....
	}
}
?>

v layoutu mam na zobrazeni komponent

{control loginForm}
<br><br><br>
{control insertForm}
<br><br><br>

a vyhazuje mi to chybu

Component with name ‚insertForm‘ does not exist.

Pritom tu loginForm to normalne zobrazuje, kdyz odstranim ten widget na insertForm. To bude nejaka prkotina, ale uz fakt nevim cim to je.

verze nette Nette Framework 0.9 (revision c82239a released on 2009–08–17)

predem diky

jasir
Člen | 746
+
0
-

máš na konci továrničky return $form?

Ani
Člen | 226
+
0
-

Diky, asi tak dve vteriny po napsani prispevku sem tam neco prohodil a bylo to tim returnem a predtim sem na to koukal asi hodinu… klasika.

Nicmene co presne dela ten widget? Pripadne kdyz budu mit komponentu, ktera nevraci form, tak se da zobrazit jak? Tohle sem nikde moc zdokumentovany nenasel.

timbulko
Člen | 85
+
0
-

Nicmene co presne dela ten widget? Pripadne kdyz budu mit komponentu, ktera nevraci form, tak se da zobrazit jak? Tohle sem nikde moc zdokumentovany nenasel.

widget v podstate iba zavola $this->getComponent(„nazov“)->render(), pripadne renderNieco(parametre). Samotny createComponent moze vracat akukolvek instanciu komponenty (ci uz Form, ale tvoje vlastne komponenty). Cize mozes si napriklad vytvorit triedu MojaKomponenta a v nej mat metodu render() a instanciu tejto triedy potom vracat pomocou createComponent (napriklad cez return new MojaKomponenta;)

Ani
Člen | 226
+
0
-

Mno, tak se do toho pomalu dostavam a mel bych jeste jeden dotaz…

Vytvorim si komponentu, ktera vezme tabulku z databaze, vytvori mi formular na pridani prvku do tabulky.
To mi funguje, az na to, ze nevim jak predat ty komponente promenou s nazvem tabulky. Jediny co me slo bylo pres persistentni promenou. Jenze ja bych to potreboval predat jako parametr pri vykreslovani komponenty, abych si mohl na jedne strance vykreslit tu komponentu pro vic tabulek.

jasir
Člen | 746
+
0
-

Třeba

<?php
{control tableForm:users}
?>

‚users‘ pak přijde jako parametr metody render komponenty tableForm:

<?php
	class TableFormControl extends Control {
	...
		public render ($table) {
		...
		}
	...
	}
?>

Nebo v metodách render<View> presenteru…

<?php
	class SomePresenter extends Presenter {
		public function renderEditor() {
			$this["tableForm"]->setTable('users')
		}
	}
?>
Ondřej Mirtes
Člen | 1536
+
0
-

Není na to v render metodě už pozdě? Osobně bych to dal do action*.

Ani
Člen | 226
+
0
-

Tak, ale to bych si musel vytvorit tridu pro tu komponentu a nemohl bych to mit v ty tovarnice? Mam pocit ze mi tu neco dulezityho unika.

jasir
Člen | 746
+
0
-

Okej, možná jsem tě zmátl. Vycházel jsem z tvé věty: „Vytvorim si komponentu, ktera vezme tabulku z databaze, vytvori mi formular na pridani prvku do tabulky“.

Svým příspěvkem jsem myslel to, že máš tedy vlastní komponentu (nikoliv AppForm) který obsahuje mimojiné AppForm. Pojmenoval jsem jí tam TableFormControl.
Taková komponenta pak sama může obsahovat AppForm, továrničky atd.
A současně může mít tebou definovanou metodu render($table).

Ty ale zřejmě jako komponentu máš instanci AppForm, kterou navíc chceš vytvářet na základě nějakého parametru. AppForm je ale definovaný jen jednou, a v průběhu render ho již měnit nemůžeš, aby jsi ji vykreslil vícekrát s různými parametry.

Editoval jasir (5. 9. 2009 11:15)

Ani
Člen | 226
+
0
-

Ok, ted uz mi to doslo, jak to vlastne funguje. Diky.

Ani
Člen | 226
+
0
-

Tak uz jsem to nejak rozchodil, ale mel bych jeste par dotazu.

Takhle vypada ta komponenta

<?php
class InsertFormControl extends Control {

    private $table;
    private $db;

    public function  createComponentInsertForm(){
        $this->db = dibi::getConnection();
        $table = $this->table;

        $culomns = $this->db->getDatabaseInfo()->getTable($table)->getColumns();

        $form = new AppForm;
        $form->addHidden('table')->value = $table;

        foreach ($culomns as $culomn) {
            if ($culomn->isAutoIncrement())
                $form->addHidden($culomn->getName())->value = 'NULL';
            else if ($culomn->getNativeType() == "VARCHAR")
                $form->addText($culomn->getName(), $culomn->getName() . ':');
            else if ($culomn->getNativeType() == "INT")
                $form->addText($culomn->getName(), $culomn->getName() . ':');
            else if ($culomn->getNativeType() == "TEXT")
                $form->addText($culomn->getName(), $culomn->getName() . ':');
        }

		$form->addSubmit('login', 'Vložit');

		$form->onSubmit[] = array($this, 'insertFormSubmitted');

        return $form;
     }

    public function render() {
		$template = $this->createTemplate();
        $template->form = $this->getComponent('insertForm');
        $template->setFile(dirname(__FILE__) . '/insertForm.phtml');
		$template->render();
    }

    public function setTable($table) {
        $this->table = $table;
    }

	public function insertFormSubmitted(AppForm $form) {
        foreach ($form->getValues() as $culomn => $data) {
            if ($culomn == 'table')
                $table = $data;
            else
               $arr[$culomn] = $data;
        }
        $this->db->query('INSERT INTO %n', $table, $arr);
    }
}
?>

a pak si v presenteru, kde potrebuju tu komponentu vytvorim

<?php
    public function actionDefault() {
        $ifc = new InsertFormControl;
	$this->addComponent($ifc, 'insertForm');
        $this["insertForm"]->setTable('producer');
    }
}
?>

kdyz potrebuju dva ty formulare, tak vytvorim dalsi instanci IsertFormControl a pridam si dalsi komponentu.

a v sablone to zavolam jako
{control insertForm}

Zajimalo by me jestli je to z pohledu zkusenejsiho cloveka spravne reseni, nebo jestli se tam dopoustim nejakych chyb.

A pak mam problem, kdyz sem v komponente udelal public render ($table) a v rablone volal {control insertForm:jmenotabulky}, tak to nefungovalo.

jasir
Člen | 746
+
0
-
  • nemusíš volat this->createTemplate(), rovnou přistupuj přes $this->template
  • i v komponentě si můžeš šahat na podkomponenty pomocí $this[‚componentName‘]
  • tím ‚culomn‘ asi myslíš ‚column‘

Proč ti nefungoval {control insertForm::table} – tady se omlouvám, {widget} funguje malinko jinak

  • {control component}$control->getWidget('component')->render()
  • {control component:table} -> `$control->getWidget('component')->renderTable()
  • {control component:table users} -> `$control->getWidget('component')->renderTable('users')

Čili v tvém případě mělo být:

{control tableform $table}

Editoval jasir (6. 9. 2009 20:14)