ZF2: изменить сценарий представления из фабрики контроллеров
В ZF2 у меня есть 2 помощника. У помощника есть форма и картограф для взаимодействия с базой данных. Я передаю эти помощники контроллеру, используя фабрику контроллеров. Контроллер управляет телефонами и адресами стороны, которая является человеком или организацией. Поскольку сторона - это человек или организация, она имеет разные данные, поэтому фабрика контроллеров также передает объект: PersonObject или OrganizationObject с данными, относящимися к стороне, в контроллер.
2 помощника одинаковы для обоих типов партий. Но в сценарии представления я хочу показать данные для конкретной стороны, и вот моя проблема: мне нужно изменить сценарий представления на основе объекта, который фабрика контроллеров передает контроллеру. Я думал о наличии двух разных контроллеров, но это излишне: сценарий представления на 90% одинаков, за исключением той 10% информации о стороне, которая поступает из базы данных в объект стороны.
Как изменить скрипт вида из фабрики контроллеров? Под изменением здесь я подразумеваю немного другой формат HTML с данными, специфичными для партии.
РЕДАКТИРОВАТЬ:
@Saeven предложил опубликовать некоторый код. На данный момент я решил создать ViewModel
на заводе контроллера подготовьте его соответствующим образом и введите в контроллер. Но я не уверен, что это хорошо.
Помощник:
class ContactMechanismRegistrationViewHelper extends AbstractRegistrationViewHelper
{
public function __construct(
FormInterface $form,
ContactMechanismMapperInterface $contactMechanismMapper
) {
$this->form = $form;
$this->mapper = $contactMechanismMapper;
}
public function saveToDb()
{
$this->mapper->save(
$this->form->get('contactMechanismFieldset')->getObject(),
$this->form->get('partyFieldset')->getObject()
);
}
}
Вспомогательная фабрика:
class ContactMechanismRegistrationViewHelperFactory implements FactoryInterface, MutableCreationOptionsInterface
{
use MutableCreationOptionsTrait;
public function createService(ServiceLocatorInterface $serviceLocator)
{
$serviceManager = $serviceLocator->getServiceLocator();
$formElementManager = $serviceManager->get('FormElementManager');
if (in_array('phone', $this->creationOptions)) {
return new ContactMechanismRegistrationViewHelper(
$formElementManager
->get('Parties\Forms\Forms\ContactMechanisms\PhoneRegistrationForm'),
$serviceManager
->get('Parties\Mappers\ContactMechanisms\PhoneMapper')
);
} elseif (in_array('address', $this->creationOptions)) {
return new ContactMechanismRegistrationViewHelper(
$formElementManager
->get('Parties\Forms\Forms\ContactMechanisms\AddressRegistrationForm'),
$serviceManager
->get('Parties\Mappers\ContactMechanisms\AddressMapper')
);
} else {
throw new ServiceNotCreatedException('wrong option type specified');
}
}
}
Контроллер, использующий помощника:
class PartyDetailsController extends AbstractActionController
{
protected $phoneViewHelper;
protected $addressViewHelper;
protected $partyViewModel;
public function __construct(
ContactMechanismRegistrationViewHelper $phoneViewHelper,
ContactMechanismRegistrationViewHelper $addressViewHelper,
ModelInterface $viewModel
)
{
$this->phoneViewHelper = $phoneViewHelper;
$this->addressViewHelper = $addressViewHelper;
$this->viewModel = $viewModel;
}
public function indexAction()
{
$request = $this->getRequest();
if ($request->isPost()) {
$viewHelperForFormSubmission = $this->getViewHelperForFormSubmission(
$request->getPost('submitButton')
);
$viewHelperForFormSubmission->getForm()->setData($request->getPost());
$viewHelperForFormSubmission->getForm()->setIsSubmitted(true);
if ($viewHelperForFormSubmission->getForm()->isValid()) {
try {
$viewHelperForFormSubmission->saveToDb();
$viewHelperForFormSubmission->getForm()->resetForm();
} catch (\Exception $e) {
die($e->getMessage());
}
} else {
$viewHelperForFormSubmission->getForm()->highlightInvalidElements();
}
}
return $this->viewModel->setVariables([
'phoneForm' => $this->phoneViewHelper->getForm(),
'addressForm' => $this->addressViewHelper->getForm(),
]);
}
protected function getViewHelperForFormSubmission($submitValue)
{
if ($submitValue == 'phone') {
return $this->phoneViewHelper;
} elseif ($submitValue == 'address') {
return $this->addressViewHelper;
} else {
throw new \Exception('invalid submit argument');
}
}
}
1 ответ
Пересмотрев мой вопрос чуть менее года спустя, решил поделиться своим опытом, возможно, он кому-нибудь пригодится.
Я пошел на разные сценарии просмотра в зависимости от типа партии. Я создал фабрику, которая создает экземпляр модели представления на основе типа вечеринки. Вполне нормально вводить модель представления из фабрики контроллеров в контроллер. Фактически, если вы создаете фабрику для модели представления, вы можете повторно использовать ее как часть модели представления какого-либо другого модуля, прикрепив ее как дочерний элемент главной ViewModel
, Иногда это очень полезно, если вам нужно межмодульное взаимодействие.
Я узнал, что идея FormViewHelpers
не очень хорошо в моем случае, потому что это добавляет ненужную сложность и иерархию, потому что все, что мой FormViewHelpers
сделал, чтобы передать вызов прямо в службу или маппера. Просто сервис с зависимостями (или маппер) и форма в контроллере сделали для меня хорошо. FormViewHelpers
, в принципе не плохая идея, ЕСЛИ (!) есть достаточно логики.
Да, и, кстати, есть замечательная статья @yourcommonsense на www.phpdelusion.net, которая описывает (im) правильное использование блоков try и catch. Это главное сообщение, что использование try... catch...
когда у вас есть определенный сценарий для восстановления ошибки. В остальном сам PHP довольно хорош с сообщениями об ошибках.
Вот и все. Удачи тому, кто в моих предыдущих туфлях.:-)