在大多数情况下, 数据库中没有外部关系的表远非现实。这意味着你将始终至少有一个从表到另一表的外部关系, 而忽略项目的类型。在Symfony项目中使用Doctrine实现的”多对多关系”中, 可能会令人头疼, 但是, 如果你发现了如何正确实现的方法, 那么你的表单中肯定会有EntityType字段。在本文中, 我们将创建一个简单的示例, 说明游戏与类别之间的关系, 在这种情况下, 每个游戏都可以与许多类别相关联, 这意味着在我们的游戏形式中, 我们将为用户提供选择哪个类别的可能性。与游戏相关, 因此我们的实体字段将呈现为多个复选框, 并且显然允许进行多个选择:
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Form\FormInterface;
// Add reference to the Categories Entity and EntityType field
use AppBundle\Entity\Categories;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
class GamesType extends AbstractType
{
// ... //
public function buildForm(FormBuilderInterface $builder, array $options)
{
// ... //
// Add the field "Categories" to the GamesForm
$form->add('Categories', EntityType::class, [
// Multiple selection allowed
'multiple' => true, // Render as checkboxes
'expanded' => true, // This field shows all the categories
'class' => Categories::class, 'mapped' => false
]);
// ... //
}
// ... //
}
在游戏实体的Twig表单中, 我们可以轻松地使用form_row渲染该字段, 或使用Twig一次渲染整个表单:
{{ form_start(games_form) }}
{#
Render all widgets of the Form
#}
{{ form_widget(games_form) }}
<input type="submit" value="Create Game" />
{{ form_end(games_form) }}
但这将在我们的项目中产生以下输出:
根据你的CSS或设计规则, 你不希望这样做, 因为它对你和用户来说都很难看。在我们的项目中, 每个类别都有一个图标(图像), 并且我们希望能够显示带有相同复选框的某种面板, 但是该面板也显示类别和图标的名称, 为此, 我们需要检索每个每个复选框的实体。
使用Twig检索实体对象
你需要知道的第一件事是, 当使用扩展并允许多个选择的EntityType字段时, 默认窗口小部件会呈现一组复选框, 因此你可以使用for循环对其进行迭代。在我们的GamesForm中, 类别字段被命名为”类别”, 我们可以将每个小部件呈现为:
{% for CategoryField in GamesForm.Categories %}
<div>
{{ form_row(CategoryField) }} <br>
</div>
{% endfor %}
但是它仍然很难看(尽管我们现在知道如何自定义它):
如前所述, 每个类别实体都有一个属性, 即icon, 用于存储每个类别的图标的名称, 因此我们可以生成一个精美的小部件, 以检索其实体的形式选择类别, 以知道哪个是每个实体的Icon。这可以通过以下方式实现:
{% for CategoryField in GamesForm.Categories %}
{# store index of the category in a variable #}
{% set index = CategoryField.vars.value %}
{# get entity object from its index in the Categories Field #}
{% set entity = GamesForm.Categories.vars.choices[index].data %}
{#
The entity variable contains a CategoryEntity with all its properties.
So we can now render
#}
<div class="col-md-4">
<div class="nk-feature-1">
<div class="nk-feature-icon">
<!-- Render the Icon of the Category -->
<img src="{{ asset('uploads/icons/' ~ entity.icon ) }}" alt="">
</div>
<div class="nk-feature-cont">
<h3 class="nk-feature-title">
{{ form_label(category_type) }}
</h3>
<h3 class="nk-feature-title text-main-1">
{{ form_widget(category_type) }}
</h3>
</div>
</div>
</div>
{% endfor %}
在我们的项目中哪个会生成以下小部件:
看起来更好吧?如你所见, 可以从包含该字段选择的form.FieldName.vars.choices对象中检索EntityType字段的每个复选框的实体。为了获得正确的实体, 你只需要指定options数组的索引并从data属性中检索该实体。
编码愉快!
评论前必须登录!
注册