Как правильно увлажнять и извлекать Учения из Zend Forms
Я только начинаю с Doctrine и переписываю некоторый код для использования сущностей Doctrine в некоторых формах.
У меня есть Entity Business, который имеет отношения 1:n с адресами, сотрудниками, электронными письмами и т. Д. Настройка действительно проста и работает нормально.
Чтобы добавить новые предприятия, я создал BusinessForm и Fieldsets для каждой из моих сущностей. Вот конструктор формы:
public function __construct($scenario='create', $entityManager = null) {
parent::__construct('business_form');
$this->scenario = $scenario;
$this->entityManager = $entityManager;
$this->setAttribute('method', 'post');
$businessFieldset = new BusinessFieldset($this->entityManager);
$businessFieldset->setUseAsBaseFieldset(true);
$this->add($businessFieldset);
$hydrator = new DoctrineHydrator($this->entityManager, new Business());
$this->setHydrator($hydrator);
$this->addElements();
$this->addInputFilter();
}
addElements просто добавляет данные Submit и CSRF.
А вот действие контроллера:
public function addAction(){
$form = new BusinessForm('create', $this->entityManager);
if ($this->getRequest()->isPost()) {
$data = $this->params()->fromPost();
$form->setData($data);
if($form->isValid()) {
// save Object
return $this->redirect()->toRoute('subcontractor', ['action'=>'index']);
}
}
return new ViewModel([
'form' => $form
]);
}
Форма проверяется, и я могу получить данные из формы с $form->getData()
, Но я не могу понять, как получить заполненный объект из формы, используя гидратор формы. Когда я использую setObject(new Business())
в начале контроллера я получаю ошибку в то время как $form->isValid()
бежит:
Zend\Hydrator\ArraySerializable::extract expects the provided object to implement getArrayCopy()
Разве это не неправильный гидратор вызывается?
Если я не setObject()
но вместо этого используйте $form->bind(new Business())
после проверки я получаю пустой объект из $form->getObject()
, Если я получу данные и увлажню новый объект с помощью гидратора формы, вот так: $form->getHydrator()->hydrate($data['business], new Business())
я получаю населенный объект, который я ожидал. (Бизнес является названием базового набора полей)
Итак, мой вопрос, как я могу получить результат последнего вызова от просто использования $form->getObject()
после проверки?
[РЕДАКТИРОВАТЬ]
Проблема, по-видимому, связана с коллекциями наборов полей, используемых в качестве наборов подполей в наборе бизнес-полей. Если я проверяю форму без использования коллекций, я получаю ожидаемый бизнес-объект от $form->getData()
Вот пример, как я могу добавить коллекцию (в бизнес-fieldset):
$this->add([
'name' => 'emails',
'type' => 'Zend\Form\Element\Collection',
'attributes' => [
'id' => 'business_emails',
],
'options' => [
'label' => 'Emails',
'count' => 1,
'should_create_template' => true,
'template_placeholder' => '__index__',
'allow_add' => true,
'target_element' => [
'type' => 'LwsSubcontractor\Form\EmailFieldset',
],
'target_class' => 'LwsSubcontractor\Entity\Email'
],
]);
и вот EmailFieldset:
public function __construct() {
parent::__construct('email');
$this->setObject(new Email());
$this->addElements();
}
protected function addElements() {
$this->add([
'name' => 'email',
'type' => 'Zend\Form\Element\Email',
'attributes' => [
'placeholder' => 'E-Mail (z.B. email@muster-email.de)',
'class' => 'form-control',
'required' => true,
'size' => 50,
],
'options' => [
'label' => 'Email',
],
]);
}
}
При использовании коллекций я получаю сообщение об ошибке сверху. Так что после добавления гидратора к каждому Fieldset я был в порядке.
Хотя у меня сложилось впечатление, что установка гидратора для формы приведет к тому, что используемые наборы полей наследуют этот гидратор. Или это произошло из-за использования наборов полей в качестве коллекций, а не напрямую?
1 ответ
Вы должны добавить гидратор для всех ваших наборов полей, лично я использую DoctrineModule\Stdlib\Hydrator\DoctrineObject
для доктринальных сущностей.
Я также хотел бы посмотреть на использование init()
метод для инициализации ваших форм и добавления элементов, а затем регистрации и извлечения ваших форм и наборов полей через FormElementManager, $serviceLocator->get('FormElementManager')->get(yourFieldsetorForm::class)
, Форма может быть затем введена в ваш контроллер.
Надеюсь, это поможет.