【问题标题】:Symfony EntityType - How to use custom layout?Symfony EntityType - 如何使用自定义布局?
【发布时间】:2017-11-15 23:43:10
【问题描述】:

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

  1. 项目
  2. 财产
  3. 类别

假设:

  • 每个项目都有多个属性。
  • 每个属性都有一个类别。
  • 每个属性都可能有父属性。

我想为 Project 实体呈现 Symfony 表单。我将EntityType 字段用于properties。但是,我不想将它们显示在一个长列表中,而是将它们分成列,以类别作为标题。

EntityType 字段的常规显示方式:

我想得到什么:

我该怎么做? - 无需在实体或视图中使用肮脏的 hack。

【问题讨论】:

  • 您可以使用自己的 HTML 表单而不是 Symfony 表单模板,在您的情况下,使用 twig 扩展来制作表单会稍微复杂一些。
  • 是的,我知道。我的观点是使用更自动化的方式是否可行 - 例如遍历Properties 的列表,但使用一些 Twig 的内置方法来打印实际输入和标签。生成像<input type="checkbox"...> 这样的原始 HTML,生成名称和 ID 对我来说听起来不是合理的解决方案。但是,如果它是唯一的,我需要走那条路。

标签: php symfony symfony-forms


【解决方案1】:

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

在 Repository 类中(拉取具有子属性和类别的所有属性的列表):

$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;
}

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

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

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

    return $propertyIds;
}

版本表单类,所以可以验证数据:

$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”部分)

但是,在我看来,这种解决方案并不理想。我宁愿摆脱在视图中手动生成&lt;input...&gt; - 我宁愿使用一些辅助函数。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 2012-06-30
    • 1970-01-01
    • 2016-10-09
    • 1970-01-01
    相关资源
    最近更新 更多