【发布时间】:2021-10-25 02:30:00
【问题描述】:
我有一个实体产品。我创建了一个带有字段的表单 ProductType :
- 姓名
- 价格
- 参考
我想创建一个集合以允许用户一次创建和提交多个产品。 因此,我创建了一个没有实体 ProductsType 的新表单。 此表单包含一个字段:
- 产品 这是一个具有条目类型 ProductType 的 CollectionType 类。
在我的模板中,我使用了一个原型,并且 Javascript 可以完美地创建它。 虽然,提交时我的条目都没有保留在数据库中。 我找了几个小时终于找到了一些鼓舞人心的东西,但仍然没有工作: Symfony: Access an unmapped form field from a CollectionType in Controller
你看到我的错误是什么(我猜是在控制器中)吗?
产品控制器
//[...]
class ProductController extends AbstractController
{
/**
* @Route("/product", name="product")
*/
public function index(): Response
{
$request = new Request();
$formProduct = $this->createForm('App\Form\ProductsType');
$product = new Product();
$formProduct->handleRequest($request);
if ($formProduct->isSubmitted() && $formProduct->isValid()) {
foreach ($formProduct->get('products') as $formChild)
{
$product->setName($formChild->get('name')->getData()); // That's it!
$product->setPrice($formChild->get('price')->getData());
$product->setReference($formChild->get('reference')->getData());
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($product);
$entityManager->flush();
}
return $this->redirectToRoute('task_success');
}
return $this->render('product/index.html.twig', [
'formProduct' => $formProduct->createView(),
]);
}
}
产品类型
//[...]
class ProductType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('price')
->add('reference')
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Product::class,
]);
}
}
产品类型
//[...]
class ProductsType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('products', CollectionType::class, [
'entry_type' => ProductType::class,
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
// Configure your form options here
]);
}
}
产品模板(树枝)
{% extends 'base.html.twig' %}
{% block title %}Hello ProductController!{% endblock %}
{% block body %}
{{ form_start(formProduct) }}
{# store the prototype on the data-prototype attribute #}
<ul id="products-fields-list"
data-prototype="{{ form_widget(formProduct.products.vars.prototype)|e }}"
data-widget-tags="{{ '<li></li>'|e }}"
data-widget-counter="{{ formProduct.products|length }}">
{% for products in formProduct.products %}
<li>
{{ form_row(products) }}
</li>
{% endfor %}
</ul>
<input type="submit" value="Submit">
{{ form_end(formProduct) }}
<button type="button"
class="add-another-collection-widget"
data-list-selector="#products-fields-list">Add another email</button>
<script>
// add-collection-widget.js
jQuery(document).ready(function () {
jQuery('.add-another-collection-widget').click(function (e) {
var list = jQuery(jQuery(this).attr('data-list-selector'));
// Try to find the counter of the list or use the length of the list
var counter = list.data('widget-counter') || list.children().length;
// grab the prototype template
var newWidget = list.attr('data-prototype');
// replace the "__name__" used in the id and name of the prototype
// with a number that's unique to your emails
// end name attribute looks like name="contact[emails][2]"
newWidget = newWidget.replace(/__name__/g, counter);
// Increase the counter
counter++;
// And store it, the length cannot be used if deleting widgets is allowed
list.data('widget-counter', counter);
// create a new list element and add it to the list
var newElem = jQuery(list.attr('data-widget-tags')).html(newWidget);
newElem.appendTo(list);
});
});
</script>
{% endblock %}
希望您能看到我缺少的东西。谢谢你:)
【问题讨论】:
-
你说“我的条目都没有被持久化”,但你没有说实际发生了什么。您是被重定向到
task_success路由还是再次收到表单(已填写或未填写)? -
确实,我没有重定向到那个页面。所以我想这意味着如果 $formProduct 已提交且 $formProduct 有效,我没有通过条件。我再次收到未填写的表格。
标签: php symfony collections symfony-forms