Symfony EntityType - 如何使用自定义布局?

Symfony EntityType - How to use custom layout?

在我的 Symfony 3.x 项目中,我有 3 个实体:

  1. 项目
  2. 属性
  3. 类别

假设:

我想为项目实体呈现 Symfony 表单。我正在为 properties 使用 EntityType 字段。但是,我不想将它们显示在一个长列表中,而是想将它们分成几列,类别为 headers.

显示 EntityType 字段的常规方式:

我想得到什么:

我该怎么做? - 不在实体或视图中使用肮脏的技巧。

所以我发现它起作用的唯一方法是:

在存储库 class 中(拉取所有具有子属性和类别的属性的列表):

$this->getEntityManager()
    ->createQueryBuilder()
    ->select('t, category, children')
    ->join('t.category', 'category')
    ->leftJoin('t.children', 'children')
    ->where('t.parent IS NULL')
    ->orderBy('category.sortOrder', 'ASC')
    ->addOrderBy('t.sortOrder', 'ASC')
    ->addOrderBy('t.name', 'ASC');

$entities = $query->getResult();

$options = [];
/** @var Property $entity */
foreach ($entities as $entity) {
    $options[$entity->getCategory()->getName()][] = $entity;
}

在实体 class 中(拉取所选属性的 ID 列表,以在视图文件中预选复选框):

public function getPropertyIds() {
    $properties = $this->getProperties();

    $propertyIds = [];
    foreach ($properties as $property) {
        $propertyIds[] = $property->getId();
    }

    return $propertyIds;
}

版本形式class,所以可以验证数据:

$builder
    ->add(
        'properties',
        EntityType::class,
        [
            'label' => 'Properties',
            'class' => Property::class,
            'choice_label' => 'name',
            'placeholder' => '',
            'expanded' => true,
            'multiple' => true,
            'required' => false,
        ]
    );

最后,视图文件:

{% for categoryName, items in properties %}
    <h2>{{ categoryName }}</h2>

    <ul>
        {% for property in items %}  
            <li>
                <input type="checkbox"
                       name="{{ form.properties.vars.full_name }}[]"
                       value="{{ property.id }}"
                       id="{{ form.properties.vars.id }}_{{ property.id }}">
                <label for="{{ form.properties.vars.id }}_{{ property.id }}">
                    {{ property.name }}
                </label>
            </li>
        {% endfor %}
    </ul>
{% endfor %}

{% do form.properties.setRendered %}

(我在视图中省略了 "checked" 和 "children" 部分)

然而,在我看来,这个解决方案并不理想。我宁愿摆脱在视图中手动生成 <input...> - 我宁愿使用一些辅助函数。

无论如何,这是对我的问题的某种低级解决方案。希望对您有所帮助。