Komponenta s výpisem dat a formulářem pro přidání a editaci

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

Trošku si teď hraji s komponentami, chci do nich naházet některé interaktivní prvky stránky a narazil jsem na problem jak řešit spojení výpisu a formuláře.

Mějmě komponentu kterou připojím v presenteru/šabloně

protected function createComponentItemsList()
{
	$component = $this->context->createComponents__itemsList();
	// Set attributes for list
	$component
		->setUser($this->userEntity)
		->setItemsPerPage(2);

	return $employments;
}
{control itemsList}

Komponentu normálně vytvořím a v její šabloně vypíšu záznamy co se mají zobrazit. Zatím vše ok. Ale jak tam vyřešit akci přidání či editace záznamu? Zatím jsem to vyřešil tak že jak pro přidání tak pro editaci mám signál: add! či edit! id ⇒ $item->id
Tento signál zpracuju v té komponentě, předám si do šablony info že se má ještě vykreslit formulář aby se tam vložil.

Co si myslíte o tomto řešení? Je korektní? Víc by se mi asi líbilo kdyby editace či přidání končilo v presenteru, ale zase při uložení toho formuláře potřebuju invalidovat snippety te komponenty pro výpis.

mkoubik
Člen | 728
+
0
-

Pokud chceš signál zpracovávat jak v komponentě tak v presenteru tak bych na to asi použil eventy z Nette\Object:

public $onEdit = array();

public function processEditForm(Form $form)
{
	$this->invalidateControl();
	$this->onEdit($form->getValues());
	$this->redirect('this');
}
akadlec
Člen | 1326
+
0
-

mkoubik: tak nutně jej v presenteru zpracovávat nemusím. Spíš řeším jak je to správně abych měl komponentu co se bude starat o výpis dat a jejich editaci. Zkoušel jsem se inspirovat v různých datagridech co mají možnost inline editace záznamu kde to +/- takto nějak řešili. Konkrétně v NiftyGridu jsem viděl ve výpisu podmínu hasActiveSubgrid() která když byla splněna tak se tam vložil subgrid editace nebo doplňujícího záznamu.

Jinak, ten editační form když jsem řešil v presenteru v původním řešení, tak jsem jej vložil v šabloně do bloku define:

{define editWindow}
....obsah formu....
{/define}

A v hlavním @layout.latte jsem tento blok includoval. Bylo to proto, že tento form byl do modalního okna. Ale v komponentě to definovaní bloku zřejmě není možné že?

A ještě jeden věc co tam řeším je vícenásobné použití jedné komponenty na jedne stránce. Na stránce mám obsah rozdělen do záložek kde je jedna záložka „Přehled“ a pak jsou detailnější záložky a právě ten výpis dat včetně možnosti editace je jak v záložce přehled tak i v záložce další. Je toto nějak řešitelné?

Oli
Člen | 1215
+
0
-

Vicenasobne pouziti komponenty na strance je mozne pres tovarnicku. Nekde v dokumentaci nebo v planette jsem videl navod. Jsem na mobilu, tak se mi to nechce hledat…

akadlec
Člen | 1326
+
0
-

Oli: Multiplier? či něco jiného? No jde mi o to že ten výpis se bude aktualizovat přes JS snippety, tak mě zajímalo jestli něco takového nette umí, že invaliduju jeden snippet v komponentě a on se invaliduje ve všech stejných.

Oli
Člen | 1215
+
0
-

Nemůžu to teď najít. Jde to i nějak víc jednoduše, ale nešlo mi to přes factory, tak to mam jen přes service takhle:

// config.neon
services:
	itemListFactory: ItemListFactory(/**zavislosti*/)

// ItemListFactory
class ItemListFactory extends \Nette\Object
{

	public function __construct(/**zavislosti*/)
	{
		...
	}

	public function create()
	{
		return new ItemList(/**zavislosti*/);
	}
}

// Presenter
public function injectItemListFactory(ItemListFactory $itemList)
{
	$this->itemList= $itemList;
}

public function createComponentItemList()
{
	return $this->itemList->create();
}

// šablona
<div>
{control itemList}
</div>
<div>
{control itemList}
</div>
<div>
{control itemList}
</div>

Tohle vytvoří 3 instance třídy ItemList. Pokud budeš mít všechny tři ve snipetu, pak si myslím, že by se měli všechny tři invalidovat nezávisle. Ale nikdy jsem to nepoužíval, tak nevím jestli to je pravda…

mkoubik
Člen | 728
+
0
-

Takhle se vytvoří jen jedna instance, která se vykreslí 3×. Pokud chceš 3 různé instance, tak si buď napiš 3 továrničky s různými názvy, nebo si přepiš createComponent($name), a nebo použij multiplier.

akadlec
Člen | 1326
+
0
-

Vykreslení x-krát je to co chci. ono to bude obsahově stejné jen na dvou místech.

Oli
Člen | 1215
+
0
-

mkoubik: nesouhlasím, možná se mýlím, ale je to právě podstata factory patternu, abych mohl vytvořit za běhu víc instancí stejného objektu. Pokaždé, když zavolám metodu create se vytvoří nová instance třídy ItemList. New ItemList(); vytvoří vždy novou instanci.

David Matějka
Moderator | 6445
+
0
-

@Oli: mylis se. ano, volani create() vzdy vytvori novou instanci, ale metoda createComponent* se zavola vzdy pouze jednou. aby to fungovalo, musel bys tam dat treba multiplier

Oli
Člen | 1215
+
0
-

Mas pravdu, omlouvam se. Nějak jsem si vsugeroval, že {component neco} zavolá createComponentNeco a tam se provede kod…

akadlec
Člen | 1326
+
0
-

okok pánové, ale zpět k meritu věci ;) jak s tím formem?