У меня есть более старый проект, в котором до сих пор используется Symfony 2. В нем есть форма для редактирования профиля клиента. В контроллере у нас есть это:
$form = $this->createForm(new ClientProfile($remindTimes), $client);
$form->handleRequest($request);
А в ClientProfile классе у нас есть
class ClientProfile extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('client_name', 'text', array('label' => 'Full name'))
->add('client_address', 'text', array('label' => 'Address', 'required' => false))
->add('client_city', 'text', array('label' => 'City', 'required' => false))
->add('client_post_code', 'text', array('label' => 'Postal index', 'required' => false))
->add('client_email', 'email', array('label' => 'E-mail', 'required' => false));
}
}
... и некоторые другие поля, но суть вы поняли. Кроме того, есть представление Twig, которое отображает HTML. Стандартные вещи, насколько я могу судить.
Теперь о моем требовании. Объект клиента имеет два специальных свойства. Назовем их FroobleEnabled и FroobleType. Если Frooble отключен, то значение типа не имеет значения (можно установить на 0). В пользовательском интерфейсе мне нужен раскрывающийся список со значениями:
Disabled
Type 1
Type 2
Type 3
Если пользователь выбирает Disabled, то FroobleEnabled устанавливается на false, а FroobleType устанавливается на 0. В противном случае FroobleEnabled устанавливается на true, а FroobleType на 1, 2 или 3 соответственно.
Как мне это сделать? Что делает это особенным, так это то, что это больше не отображение 1:1. В объекте модели есть два поля, но только один элемент управления пользовательского интерфейса. I думать Я мог бы добиться этого с помощью a DataMapper, но я также не хочу вручную сопоставлять все остальные поля (хотя я могу, если нет другого варианта). Я также не могу найти никакой достойной документации о DataMapper или любых других функциях Symfony Forms, которые могли бы мне помочь.
@geoB - я мог бы, но я хотел, чтобы пользовательский интерфейс был простым.
Альтернативой является одно поле с четырьмя возможными вариантами. Контроллер может определить правильные значения двух свойств. Это зависит от способности пользователей делать правильный выбор. Конечно, это верно и для решения с двумя полями.
@geoB - я бы очень хотел написать код, который устанавливает два свойства в зависимости от одного поля ввода. А вот куда мне этот код ставить?
Первым выбором будет контроллер.
@geoB - Ммм... Я не понимаю. См. код выше. Вот почти все, что есть в контроллере. Поля формы там даже не определены — они в классе ClientProfile. Контроллер просто создает объект формы и передает ему объект определения поля (ClientProfile) и фактическую сущность. Нет места, где я мог бы перехватить любое отображение.
Контроллеры также используются для обработки отправки форм. После отправки и проверки формы вы можете добавить логику для определения значений полей. См. эта часть документов..
Итак... Я добавляю несопоставленное поле в форму, а затем вручную обрабатываю сопоставление в контроллере?
Вот так. Контроллеры выполняют большую часть бизнес-логики.
Хорошо, я попробую это.
@geoB - Хорошо, сработало!
Поздравляем! Должен ли я резюмировать вышеизложенное в ответе?
@geoB - Было бы здорово! Я приму это.






Один из способов добиться этого — создать поле, скажем, frooble.
frooble Choice с mapped => false и значениями 0, 1, 2, 3. Установите его варианты в строки, соответствующие приложению.В контроллере после отправки и проверки формы включите код, например:
...
$frooble = $form->get('frooble')->getData();
if (0 === $frooble) {
$client->setFroobleEnabled(false);
$client->setFroobleType(0);
} else {
$client->setFroobleEnabled(true);
$client->setFroobleType($frooble);
}
Не могли бы вы использовать JavaScript, чтобы показать или скрыть
FroobleTypeв зависимости от значенияFroobleEnabled? Контроллер может изменить значениеFroobleTypeна 0, еслиFroobleTypeзаписи изменится наDisabled.