Я построил форму, которая отлично отправляет, однако все значения подчиненной формы заканчиваются нулевым значением на принимающей стороне, когда я смотрю на них в контроллере.
Вот моя форма UserProfileType, основанная на классе User. Итак, рассматриваемые нами субформы — это subscriptionTier1, subscriptionTier1 и subscriptionTier1:
class UserProfileType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('firstName', TextType::class)
->add('lastName', TextType::class)
->add('email', EmailType::class)
// etc... I'll keep out the unimportant fields
// here are the subforms whose values show up as null on the back end
->add('subscriptionTier1', UserSubscriptionTierType::class, [
'required' => false,
'mapped' => false
])
->add('subscriptionTier2', UserSubscriptionTierType::class, [
'required' => false,
'mapped' => false
])
->add('subscriptionTier3', UserSubscriptionTierType::class, [
'required' => false,
'mapped' => false
])
->add('save', SubmitType::class, [
'attr' => ['class' => 'save'],
])
;
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => User::class,
'mode' => null
)
);
}
}
Вот как выглядит мой класс типа формы UserSubscriptionTierType:
class UserSubscriptionTierType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', TextType::class, [
'attr' => [
'maxlength' => 25
]
])
->add('price', ChoiceType::class, [
'choices' => [
'$10 per month' => 10,
'$20 per month' => 20,
'$30 per month' => 30
]
])
->add('description', TextareaType::class)
->add('messaging', CheckboxType::class, [
'required' => false
])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => UserSubscriptionTier::class,
));
}
}
Как вы можете видеть на рисунке ниже, все значения имени, цены и описания подчиненной формы подпискиTier1 устанавливаются во внешнем интерфейсе:
Вот как выглядит код ветки для подформы subscriptionTier1:
<div class = "row justify-content-center w-100 ml-0 mr-0 mt-3 tier tier-1" >
<div class = "col-lg-6 mt-1">
<div class = "form-group form-control-lg w-100">
<label for = "firstname" class = "mb-2">Tier 1 Name</label>
{{ form_widget(form.subscriptionTier1.name, { 'attr': {'class': 'form-control'}}) }}
</div>
</div>
<div class = "col-lg-6 mt-1">
<div class = "form-group form-control-lg w-100">
<label for = "tier1price" class = "mb-2">Tier 1 Price</label>
{{ form_widget(form.subscriptionTier1.price, { 'attr': {'class': 'form-control'}}) }}
</div>
</div>
<div class = "col-lg-12 mt-3">
<div class = "form-group form-control-lg w-100">
<label for = "bio" class = "mb-2">Tier 1 Description
<sup class = "text-danger">*</sup>
</label>
{{ form_widget(form.subscriptionTier1.description, { 'attr': {'class': 'form-control border-box', 'rows':'8'}}) }}
</div>
</div>
<div class = "col-lg-12">
<div class = "form-group form-control-lg w-100">
<div class = "form-check">
<label class = "form-check-label">
{{ form_widget(form.subscriptionTier1.messaging, { 'attr': {'class': 'form-control form-check-input'}}) }}
<span class = "form-check-sign"></span>
Enable Messaging
</label>
</div>
</div>
</div>
</div>
Вот код на принимающей стороне, контроллере:
public function saveProfileAction(Request $request)
{
$user = $this->getUser();
$form = $this->createForm(UserProfileType::class, $user);
$form->handleRequest($request);
dump($form->get('subscriptionTier1')->getData());
Итак, при отладке, если я выгружу только первую форму subscriptionTier1, вы увидите, что все значения — null.
ProfileController.php on line 269:
Form {#2235 ▼
-config: FormBuilder {#2236 ▶}
-parent: Form {#2112 ▶}
-children: OrderedHashMap {#2237 ▶}
-errors: []
-submitted: true
-clickedButton: null
-modelData: UserSubscriptionTier {#2280 ▼
-id: null
-posts: ArrayCollection {#2323 ▶}
-subscriptions: null
-name: null // Don't understand why this is null
-price: null // Don't understand why this is null
-description: null // Don't understand why this is null
-tierNumber: null
-versionNumber: null
-messaging: false
-user: null
+"subsciptions": ArrayCollection {#2089 ▶}
}
-normData: UserSubscriptionTier {#2280 ▶}
-viewData: UserSubscriptionTier {#2280 ▶}
-extraData: []
-transformationFailure: null
-defaultDataSet: true
-lockSetData: false
}
Кто-нибудь знает, почему значения не передаются на сервер (или обнуляются)?




Поскольку параметр data_class типа формы UserProfileType установлен на класс User, данные модели будут экземпляром класса User, а поскольку класс User не имеет таких полей, как subscriptionTier1 и т. д., они не будут отображаться в ваших данных модели.
Вместо этого вы можете получить доступ к несопоставленным полям в форме в контроллере следующим образом:
$subscriptionTier1 = $form->get('subscriptionTier1')->getData();
Документация здесь
Обновлено: вы можете получить доступ только к значению subscribeTier1 и т. д., только после обработки формы и только в том случае, если форма была отправлена, иначе она будет нулевой:
public function saveProfileAction(Request $request)
{
$user = $this->getUser();
$form = $this->createForm(UserProfileType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$subscriptionTier1 = $form->get('subscriptionTier1')->getData();
dump($subscriptionTier1);
}
Привет irxs, спасибо, это было большой помощью. Теперь все значения формы равны нулю. Мне придется отредактировать вопрос. Но это все равно было большим подспорьем.
Я отредактировал свой ответ, чтобы помочь вам лучше понять его
Я не знаю, является ли это просто обходным путем или на самом деле это лучший способ сделать это, но вот как я заставил его работать:
У меня были следующие теги подчиненной формы:
{{ form_start(form.subscriptionTier1) }}
etc...
{{ form_end(form.subscriptionTier1) }}
Это будет вкладывать теги формы. Очевидно, вам не разрешено вкладывать такие формы.
Таким образом, удаление {{ form_start(form.subscriptionTier1) }} , {{ form_end(form.subscriptionTier1) }} для всех subscriptionTier1, subscriptionTier1, subscriptionTier1, а затем проверка значений формы в объекте запроса сработали.
Если его нет в объекте
Request(вы также можете проверить необработанные данные$_POST), то вам следует проверить отображаемый HTML. Если данные не приходят с запросом, вы мало что можете сделать на стороне сервера.