zf2 / zf3 Увлажнение нескольких наборов полей с объектами

Проблема: при использовании $ form-> bind ($ object) несколько наборов полей в форме не заполняются / не обрабатываются. Как заполнить 2 разных набора полей в форме 2 разных объекта сущности?
У меня есть 2 набора полей: FieldsetA, FieldsetB

Форма RegisterFrom вызывает их в своем методе init ()

class RegisterForm extends Form
{
public function init(){
$this->add(array(
'name' => 'service_provider_fieldset',
'type' => ServiceProviderFieldset::class,   // this is one model/entity
));

$this->add(array(
'name' => 'location_fieldset',
'type' => LocationFieldset::class,   // this is a separate model/entity
));
}
}

Создание наборов полей: (обратите внимание, закомментированы попытки гидратации)

class ServiceProviderFieldset extends Fieldset
{
public function init(){
//parent::__construct($name);
/*
$this
->setHydrator(new ClassMethodsHydrator(false))
->setObject(new ServiceProvider())
;
*/

/*
$this
->setHydrator(new ReflectionHydrator(false))
->setObject(new ServiceProvider())
;
*/

$this->add(array(
'type'=>'Hidden',
'name'=>'id',
'options'=>array(
'label' => 'Service Provider Id'
),
'attributes'=>array(
'id'=>'providerId'
)
));
}
}

контроллер:

    $provider = $this->findServiceProviderById($providerId); // this is set from DB call and correctly creates a Provider() object with populated values.
$location = $this->findServiceProviderLocationById($locId);
$form = $formManager->get(RegisterForm::class);
$form->bind($provider);
$form->bin($location);
// $form->get('service_provider_fieldset')->bindValues(...);

Посмотреть:

$formElement = $form->get('service_provider_fieldset')->get('email');
etc...

Форма отображается в представлении правильно, НО без заполненных данных.

ПРИМЕЧАНИЕ: НЕ использую Doctrine, но я получаю данные из БД в порядке.
ПРИМЕЧАНИЕ: ЕСЛИ я установил этот флаг ‘use_as_base_fieldset’ => true, затем заполняется 1 из объектов (ServiceProvider), наоборот, если я установлю для полей местоположения значение ‘true’, то заполняется.
Я искал пару часов, методом проб и ошибок, но безуспешно, и я надеюсь, что это просто моя усталость, которая пропустила простой шаг настройки / настройки, чтобы заставить это работать.

Описание: Как вы заполняете 2 или более набора полей двумя или более объектами в форме?
Bind (), fieldset-> bindValues ​​() ?,

Пытался:

$form->get('service_provider_fieldset')->allowObjectBinding(true);
$form->get('service_provider_fieldset')->allowedObjectBindingClass(\Provider\Form\ServiceProviderFieldset::class);

Это некоторые ссылки, которые близки, но по-прежнему не могут заполнять оба набора полей через отдельные объекты.
ZF2 Form Hydration с несколькими объектами и наборами полей
https://framework.zend.com/manual/2.4/en/modules/zend.form.collections.html
увлажнение нескольких объектов из наборов полей ZF2

Пример коллекции (продукт / марка / категория) подразумевает «единую» коллекцию с использованием ‘use_as_base_fieldset’ => true, используется для связывания () …?

1

Решение

На вашей веб-странице проверьте имена элементов формы, которые относятся к вашим наборам полей. Они должны быть примерно такими: yourFieldsetName[yourElementName], Если вы просто видите yourElementName, что, скорее всего, означает, что забыл prepare() Ваша форма в сценарии просмотра.

Это именно то, что случилось со мной, и после того, как я prepare()Под воздействием формы все объекты гидратировались без проблем.

ОБНОВЛЕНИЕ = ответ на вопросы комментария: Не решен как таковой. Это плохой дизайн? Примечание. Я использую prepare () в представлении.

Если все работает нормально, ваши 2 объекта должны увлажняться. use_as_base_fieldset Флаг используется для того, чтобы сказать: «Эй, это я (набор полей), вы должны только гидрировать объект данными / извлекать данные из объекта». То, что вы получаете, когда один объект гидратируется, а другой нет, и наоборот, предсказуемо. Довольно сложно сказать, что происходит, не глядя на ваш полный код. Боюсь, что публикация слишком большого количества сообщений также займет время, чтобы понять ответчика, и мой опыт показывает, что такие вопросы обычно остаются без ответа. В таких ситуациях, как ваша, я обычно делаю шаг за шагом в Zend Formи Fieldsets методы, используемые в гидратации / экстракции. я использую \Zend\Debug\Debug::dump($somethingThatYouWantToCheck); die();, Я предполагаю, что это не лучший метод, но он работает.

На твоем месте я бы тоже сделал следующее.

  1. Из вашего поста не понятно, почему вы используете форму init() метод. init() Метод используется, когда вы хотите, например, чтобы некоторые элементы в вашей форме были заполнены из БД (например, <select>). Form работает init() метод, когда некоторые вещи, которые не доступны в __construct() метода пока нет, но только после того, как экземпляр формы создан (не уверен на 100% в этом, перепроверьте это).

  2. Не беспокойтесь о хорошем / плохом дизайне. Дизайн — это очень хорошая вещь, но если у вас небольшая или средняя система, соображения дизайна не влияют на производительность / сложность системы. Но скорее вы потратите действительно много времени, делая все правильно, чем просто делая это, и если это работает хорошо, забывая об этом.

  3. Если ты не хочешь идти с \Zend\Debug\Debug::dump($somethingThatYouWantToCheck); die(); (это может быть довольно утомительно, я знаю), создайте один набор полей и прикрепите к нему желаемые 2 набора полей. Затем включите этот набор полей в форму и используйте use_as_base_fieldset = true на этом наборе полей (конечно, вам также нужно создать объект, соответствующий этому набору полей, с двумя вложенными объектами, которые прикреплены к вашим текущим наборам полей, и прикрепить объект к набору полей).

Надеюсь, это поможет хоть немного.

0

Другие решения

Для работы с несколькими объектами вам необходимо:

1. Создайте форму с набором полей для каждого объекта, как вы это сделали.
Ты должен укажите имя для каждого набора полей (например, в конструкторе).

2. В каждом наборе полей нам нужно указать гидратор
например.: $this->setHydrator(new ClassMethods());

Zend \ Hydrator \ методы класса для использования функций геттера или
Zend \ Hydrator \ ArraySerializable для использования метода getArrayCopy.

и разрешить класс объекта:

$this->setAllowedObjectBindingClass(YourClassObject::class);

Вы можете сделать это в в этом метод в fieldset.

3. Установите гидратор для основной формы:

$this->setHydrator(new ArraySerializable());

4. Теперь в методе контроллера вы можете создать объект Zend \ Stdlib \ ArrayObject:

$obj = new ArrayObject();

затем добавьте ваши объекты с ключом равным имени fieldset:

$obj->offsetSet("fieldset_name", $your_object);

и тогда вы можете привязать $ obj к вашей форме:

$form->bind($obj);

Надеюсь, это поможет. И не забудьте о методе подготовки:

return new ViewModel(["form" => $form->prepare()]);
0

По вопросам рекламы [email protected]