Повторно използване на формуляри на различни места
В Nette имате няколко възможности за повторно използване на една и съща форма на няколко места, без да дублирате код. В тази статия ще разгледаме различните решения, включително и тези, които трябва да избягвате.
Фабрика за формуляри
Един от основните подходи за използване на един и същ компонент на няколко места е да се създаде метод или клас, който генерира компонента, и след това да се извика този метод на различни места в приложението. Такъв метод или клас се нарича фабрика. Моля, не бъркайте с шаблона за проектиране фабричен метод, който описва специфичен начин за използване на фабрики и не е свързан с тази тема.
Като пример, нека създадем фабрика, която ще изгради форма за редактиране:
Сега можете да използвате тази фабрика на различни места в приложението си, например в презентатори или компоненти. Това става, като я заявяваме като зависимост. Затова първо ще запишем класа в конфигурационния файл:
И след това ще го използваме в презентатора:
Можете да разширите фабриката за формуляри с допълнителни методи, за да създадете други видове формуляри, подходящи за вашето приложение. И, разбира се, можете да добавите метод, който създава основна форма без елементи, която другите методи ще използват:
Методът createForm()
все още не прави нищо полезно, но това бързо ще
се промени.
Зависимости на фабриката
С течение на времето ще стане ясно, че е необходимо формулярите да
бъдат многоезични. Това означава, че трябва да настроим преводач за всички форми. За да
направим това, модифицираме класа FormFactory
, за да приеме обекта
Translator
като зависимост в конструктора и да го предаде на
формата:
Тъй като методът createForm()
се извиква и от други методи, които
създават конкретни форми, трябва да зададем преводача само в този
метод. И сме готови. Не е необходимо да променяме какъвто и да е код на
презентатора или компонента, което е чудесно.
Още фабрични класове
Като алтернатива можете да създадете няколко класа за всяка форма,
която искате да използвате в приложението си. Този подход може да
увеличи четимостта на кода и да улесни управлението на формулярите.
Оставете оригиналния FormFactory
за създаване само на чиста форма с
основна конфигурация (например с поддръжка на превод) и създайте нова
фабрика EditFormFactory
за формата за редактиране.
Много е важно връзката между класовете FormFactory
и
EditFormFactory
да се осъществява чрез композиция,
а не чрез наследяване на
обекти:
Използването на наследяване в този случай би било напълно
непродуктивно. Много бързо ще се сблъскате с проблеми. Например, ако
искате да добавите параметри към метода create()
; PHP ще отчете
грешка, че сигнатурата му е различна от тази на родителя. Или при
предаване на зависимост на класа EditFormFactory
чрез конструктора.
Това би довело до това, което наричаме " ад на конструкторите".
Като цяло е по-добре да се предпочита композицията пред наследяването.
Обработка на формуляри
Обработчикът на формуляри, който се извиква след успешно изпращане,
може също да бъде част от фабричен клас. Той ще работи, като предава
изпратените данни на модела за обработка. Той ще предаде всички грешки
обратно към формата. Моделът в
следващия пример е представен от класа Facade
:
Нека водещият сам се справи с пренасочването. Той ще добави друг
обработващ към събитието onSuccess
, който ще извърши
пренасочването. Това ще позволи формулярът да се използва в различни
презентатори, като всеки от тях може да пренасочва към
различно място.
Това решение се възползва от свойството на формите, че когато се
извика addError()
на форма или неин елемент, не се извиква следващият
обработващ onSuccess
.
Наследяване от класа Form
Вградената форма не трябва да бъде дете на форма. С други думи, не използвайте това решение:
Вместо да изграждате формата в конструктора, използвайте фабриката.
Важно е да осъзнаете, че класът Form
е преди всичко инструмент за
сглобяване на формуляр, т.е. конструктор на формуляри. А сглобената
форма може да се счита за негов продукт. Продуктът обаче не е
специфичен случай на конструктора; между тях няма има връзка, която
е в основата на наследяването.
Компонент на формата
Съвсем различен подход е да създадете компонент, който включва формуляр. Това дава нови възможности, например да визуализирате формуляра по определен начин, тъй като компонентът включва шаблон. Или пък могат да се използват сигнали за AJAX комуникация и зареждане на информация във формата, например за подсказване и т.н.
Нека да създадем фабрика, която ще произвежда този компонент. Достатъчно е да напишем нейния интерфейс:
И да го добавим към конфигурационния файл:
И сега можем да поискаме фабриката и да я използваме в презентатора: