个性化阅读
专注于IT技术分析

如何在Symfony 3表单内使用Twig检索EntityType字段的每个实体实例

在大多数情况下, 数据库中没有外部关系的表远非现实。这意味着你将始终至少有一个从表到另一表的外部关系, 而忽略项目的类型。在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) }}

但这将在我们的项目中产生以下输出:

Twig自定义渲染与实体

根据你的CSS或设计规则, 你不希望这样做, 因为它对你和用户来说都很难看。在我们的项目中, 每个类别都有一个图标(图像), 并且我们希望能够显示带有相同复选框的某种面板, 但是该面板也显示类别和图标的名称, 为此, 我们需要检索每个每个复选框的实体。

使用Twig检索实体对象

你需要知道的第一件事是, 当使用扩展并允许多个选择的EntityType字段时, 默认窗口小部件会呈现一组复选框, 因此你可以使用for循环对其进行迭代。在我们的GamesForm中, 类别字段被命名为”类别”, 我们可以将每个小部件呈现为:

{% for CategoryField in GamesForm.Categories %}
    <div>
        {{ form_row(CategoryField) }} <br>
    </div>
{% endfor %}

但是它仍然很难看(尽管我们现在知道如何自定义它):

Twig实体字段自定义渲染

如前所述, 每个类别实体都有一个属性, 即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 %}

在我们的项目中哪个会生成以下小部件:

Twig检索EntityType字段的Entity

看起来更好吧?如你所见, 可以从包含该字段选择的form.FieldName.vars.choices对象中检索EntityType字段的每个复选框的实体。为了获得正确的实体, 你只需要指定options数组的索引并从data属性中检索该实体。

编码愉快!

赞(0)
未经允许不得转载:srcmini » 如何在Symfony 3表单内使用Twig检索EntityType字段的每个实体实例

评论 抢沙发

评论前必须登录!