Ponovna uporaba obrazcev na več mestih
Kako ponovno uporabiti isti obrazec na več mestih in ne podvajati kode? To je v programu Nette zelo enostavno, na voljo pa imate več načinov, med katerimi lahko izbirate.
Tovarna obrazcev
Ustvarimo razred, ki lahko ustvari obrazec. Takšen razred se imenuje tovarna. Na mestu, kjer želimo uporabiti obrazec (npr. v predstavitvenem programu), zahtevamo tovarno kot odvisnost.
Del tovarne je koda, ki posreduje podatke v nadaljnjo obdelavo, ko je obrazec uspešno oddan. Običajno na modelno plast. Prav
tako preveri, ali je vse potekalo dobro, in morebitne napake posreduje nazaj obrazcu. Model v naslednjem primeru
predstavlja razred Facade
:
use Nette\Application\UI\Form;
class EditFormFactory
{
public function __construct(
private Facade $facade,
) {
}
public function create(/* parameters */): Form
{
$form = new Form;
// dodajanje elementov v obrazec
$form->addSubmit('send', 'Submit');
$form->onSuccess[] = [$this, 'processForm'];
return $form;
}
public function processForm(Form $form, array $values): void
{
try {
// obdelava obrazca
$this->facade->process($values);
} catch (AnyModelException $e) {
$form->addError('...');
}
}
}
Tovarna je seveda lahko parametrična, kar pomeni, da lahko prejme parametre, ki bodo vplivali na videz ustvarjenega obrazca.
Sedaj bomo prikazali, kako tovarno posredujemo predstavniku. Najprej jo zapišemo v konfiguracijsko datoteko:
services:
- EditFormFactory
Nato jo zahtevamo v predstavitvenem programu. Sledi tudi naslednji korak obdelave oddanega obrazca, to je preusmeritev na naslednjo stran:
class MyPresenter extends Nette\Application\UI\Presenter
{
public function __construct(
private EditFormFactory $formFactory,
) {
}
protected function createComponentEditForm(): Form
{
$form = $this->formFactory->create();
$form->onSuccess[] = function (Form $form) {
$this->redirect('this');
};
return $form;
}
}
Ker je preusmeritev urejena s strani izvajalca predstavitve, lahko komponento uporabimo na več mestih in jo na vsakem mestu preusmerimo drugam.
Komponenta z obrazcem
Drug način je, da ustvarite novo komponento, ki vsebuje obrazec. To nam daje možnost, da obrazec prikažemo na določen način, na primer zato, ker komponenta vsebuje predlogo. Lahko pa uporabimo signale za komunikacijo AJAX in nalaganje informacij v obrazec, na primer za samodejno dokončanje itd.
use Nette\Application\UI\Form;
class EditControl extends Nette\Application\UI\Control
{
public $onSave;
public function __construct(
private Facade $facade,
) {
}
protected function createComponentForm(): Form
{
$form = new Form;
// dodajanje elementov v obrazec
$form->addSubmit('send', 'Submit');
$form->onSuccess[] = [$this, 'processForm'];
return $form;
}
public function processForm(Form $form, array $values): void
{
try {
// obdelava obrazca
$this->facade->process($values);
} catch (AnyModelException $e) {
$form->addError('...');
return;
}
// priklic dogodka
$this->onSave($this, $values);
}
}
Nato bomo ustvarili tovarno, ki bo izdelala to komponento. Napišite njen vmesnik:
interface EditControlFactory
{
function create(): EditControl;
}
In dodajte v konfiguracijsko datoteko:
services:
- EditControlFactory
Zdaj lahko zahtevamo tovarno in jo uporabimo v predstavitvenem programu:
class MyPresenter extends Nette\Application\UI\Presenter
{
public function __construct(
private EditControlFactory $controlFactory,
) {
}
protected function createComponentEditForm(): Form
{
$control = $this->controlFactory->create();
$control->onSave[] = function (EditControl $control, $data) {
$this->redirect('this');
// ali preusmerite na rezultat urejanja, npr.:
// $this->reirect('detail', ['id' => $data->id]);
};
return $control;
}
}