Jak vytvorit odkaz na Edit formulare komponenty ze sablony presenteru

crookslovacko
Člen | 75
+
0
-

Jak vytvorit odkaz na Edit formulare komponenty ze sablony presenteru
Mám formulář obaleny v komponentě, který přidává kategorii. V presenteru ho vytvářím přes továrničku. V tomto presenteru pak vypisuji kategorie. Jak tedy vytvorim odkaz na actionEdit ze sablony toho presenteru ( ne ze sablony komponenty).
Handle mi funguje Tedy plink categoryForm:edit! funguje ale nevim ja to prepnout na akction…Prominte za primitivni otazku.
Handle mi ale nevytvori komponentu pred pouzitim v modal okne.

Dekuji

CZechBoY
Člen | 3608
+
0
-

{plink edit}

duke
Člen | 650
+
0
-

Akce mají pouze presentery, nikoli komponenty. A na akci „Edit“ presenteru se ze šablony presenteru odkážeš proste pomocí {link edit}, ze šablony subkomponenty {plink edit}, ale {plink} už je trochu hack, protože komponenta by neměla spoléhat na to, že bude umístěna výhradně v presenteru s nějakou konkrétní akcí.

Kcko
Člen | 470
+
0
-

duke napsal(a):

Akce mají pouze presentery, nikoli komponenty. A na akci „Edit“ presenteru se ze šablony presenteru odkážeš proste pomocí {link edit}, ze šablony subkomponenty {plink edit}, ale {plink} už je trochu hack, protože komponenta by neměla spoléhat na to, že bude umístěna výhradně v presenteru s nějakou konkrétní akcí.

A když je to hack, jak by se to mělo řešit čistěji?
Tzn když má výpis posledních novinek / článků na HP formou komponenty a chci se odkázat do detailu článku tj.
ArticlePresenter:detail $id
tak je to hack? Jak to tedy má být správně?

Editoval Kcko (23. 1. 2019 19:21)

duke
Člen | 650
+
0
-

To, že se má v daném případě subkomponenta odkazovat zrovna na ArticlePresenter:detail by ji mělo být sděleno presenterem (případně nadřazenou komponentou, která to ví od presenteru) předem. Nemělo by to být přímo v ní zadrátované. Ale často se to obchází, protože je s tím víc psaní.

Kcko
Člen | 470
+
0
-

duke napsal(a):

To, že se má v daném případě subkomponenta odkazovat zrovna na ArticlePresenter:detail by ji mělo být sděleno presenterem (případně nadřazenou komponentou, která to ví od presenteru) předem. Nemělo by to být přímo v ní zadrátované. Ale často se to obchází, protože je s tím víc psaní.

A jak má dát Presenter komponentě vědět, že se z ní na něj bude odkazovat?

Milo
Nette Core | 1283
+
0
-
$this['component']->setEditAction('Presenter:action');

anebo rovnou URL.

Kcko
Člen | 470
+
0
-

Milo napsal(a):

$this['component']->setEditAction('Presenter:action');

anebo rovnou URL.

Tak to je mi jasné, ale co třeba ID článku?
Prostě mi přijde u komponenty např. related článků v detailu článku mít odkaz na onen detail naprosto v pořádku. (Kam jinam bych měl taky linkovat z komponenty nějakých článků, než do detailu, že?)

crookslovacko
Člen | 75
+
0
-

duke Trochu teď trochu nechápu Má logika je taková Mám formulář který přidává různé kategorie, obalený komponentou. Myslel jsem tedy, že pokud chci editaci, mazání a nevím teď co ještě, tak to dám do té komponenty kde je ten formulář, ale výpis článku nechci rozhodně v komponentě, další komponentu na to vytvářet nechci, protože další věci jako např paginátor či search chci mít pospojované v presenteru, tak mi nejrozumější přišlo vypsat si vše v renderu presenteru kde chci komponenty spojovat, a jen do nich odkazovat, jako je editace při výpisu..je někde má logika špatná? Rád bych si to ujasnil než budu pokračovat. Samozřejmě..jde to i přes handleEdit ne actionEdit, ale tam se mi nepředá id článku, protože to chci v modal okně..co jsem pochopil tak v action se to předá, podle jiných diskuzí.

crookslovacko
Člen | 75
+
0
-

A omlouvám se ale asi jsme se špatně pochopili {plink edit nefunguje}..ja se potřebuju odkázat na akci komponentě ne v presenteru kde připojuju komponentu. Jak se dívám na svůj první dotaz, asi to blbě vyznělo Omlouvám se.

duke
Člen | 650
+
0
-

@crookslovacko Opakuji, že komponenty žádné akce nemají, a nelze se tudíž na ně ani odkazovat. Mají signály, na které to lze, a které také umožňují předání parametrů. Pokud chceš předat id článku do sdíleného html modálního okna, budeš si ho tam muset nakopírovat javascriptem (např. z data-atributu nějakého tagu, který je u každé položky, např. do hidden inputu ve formuláři v tom modalu či do data-atributu nějakého tagu toho modalu) před zobrazením onoho modálního okna. Např.:

$(document).ready(function () {
	$(".edit-dialog").click(function () {
		$('#itemId').val($(this).data('id'));
	});
});

… a html výpisu položky:

<li><a href="#edit" role="button" data-toggle="modal" data-id="{$item->id}" class="edit-dialog"><i class="icon-pencil"></i> Upravit</a></li>

Pokud půjdeš cestou formuláře, pošle se ti to id z toho hidden inputu. Pokud chceš prostý odkaz, budeš si na něj muset navěsit event handler na click a volat ajax ručně s tím, že id doplníš při tom volání přes klíč „data“, tj. při použití nette.ajax.js např.:

$.nette.ajax({
	type: 'get',
	url: {link editRecord!},
	data: {
		'itemId': $('#itemId').val()
	}
});

Případně si i to url můžeš předat v data atributech, a pak můžeš mít tento javascript i mimo šablonu (tj. unobtrusive). Vlastně si můžeš takto v data atributech kopírovat klidně i celá editační url s již vyplněným id a nemusíš pak kopírovat to id zvlášť a obejdeš se třeba i bez toho ručního volání (když si jen javascriptem upravíš href editačního odkazu v tom modalu). Ale to už je na tobě.

Milo
Nette Core | 1283
+
0
-

@Kcko Jde jen o zapouzdření, aby v komponentě nebyl natvrdo zadrátovaný odkaz na akci presenteru. Funguje to, ale přijde mi lepší nastavit akci editace zvenčí. Setup se potom udělá buď hromadně v továrně, nebo až v konrétní továrničce.

final class MyPresenter
{
	...

	protected function createComponentArticleList(): ArticleListControl
	{
		$comp = $this->articleListFactory->create();
		$comp->setEditLink('ArticleEdit:default');
		return $comp;
	}
}
Milo
Nette Core | 1283
+
0
-

@crookslovacko Jak bylo řečeno, komponenty nemají akce, pouze signály. Těmi můžeš řídit stav komponenty a v render() se rozhodnout, co vykreslit. Například:

class MyComponent
{
	private $mode = 'view-only';

	public function handleSignalEdit()
	{
		$this->mode = 'edit';
	}

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

		if ($this->mode === 'edit') {
			$template->setFile(__DIR__ . '/edit.latte');
		} else {
			$template->setFile(__DIR__ . '/view.latte');
		}

		# nebo cokoliv
	}
}