在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');
}
}
}
答案 0 :(得分:1)
在不到一年后重新审视我的问题后,决定分享我的经验,也许这对某人有用。
我根据派对类型选择了不同的视图脚本。我所做的是创建了一个工厂,它根据聚会的类型创建一个视图模型的实例。将视图模型从控制器工厂注入控制器是绝对可以的。实际上,如果为视图模型创建工厂,则可以将其作为主要ViewModel
的子项附加,将其作为其他模块的视图模型的一部分重用。如果您需要跨模块交互,它有时非常有用。
我发现FormViewHelpers
的概念在我的情况下并不是很好,因为它增加了不必要的复杂性和层次结构,因为我FormViewHelpers
所做的就是将呼叫直接传递给服务或映射器。只有依赖注入的服务(或映射器)和表单到控制器对我来说没问题。 FormViewHelpers
,原则上不是一个坏主意,如果(!)有一些逻辑可以放入。
啊,顺便说一句,@ yourcommonsense在www.phpdelusions.net上有一篇很棒的文章描述了(im)正确使用try和catch块。它的主要信息是,当您有某种恢复错误的方案时,请使用try... catch...
。否则PHP本身在错误报告方面非常好。
就是这样。祝我以前的鞋子好运。 : - )