【问题标题】:displaying a collection in symfony 2 form with data from a foreign table以 symfony 2 形式显示包含外部表数据的集合
【发布时间】:2015-02-17 15:02:37
【问题描述】:

我是 symfony 的新手,我无法找到解决我关于以正确方式显示表单的问题的解决方案。

我有三个表:活动、存在和人员

desc activities;
+----------+--------------+------+-----+---------+----------------+
| Field    | Type         | Null | Key | Default | Extra          |
+----------+--------------+------+-----+---------+----------------+
| id       | int(11)      | NO   | PRI | NULL    | auto_increment |
| start    | datetime     | NO   |     | NULL    |                |
| stop     | datetime     | YES  |     | NULL    |                |
| activity | varchar(100) | NO   |     | NULL    |                |
| location | varchar(45)  | NO   |     | NULL    |                |
| event_id | int(11)      | YES  | MUL | NULL    |                |
+----------+--------------+------+-----+---------+----------------+

desc presences;
+-------------+----------------------------------------------+------+-----+---------+-------+
| Field       | Type                                         | Null | Key | Default | Extra |
+-------------+----------------------------------------------+------+-----+---------+-------+
| activity_id | int(11)                                      | NO   | PRI | NULL    |       |
| person_id   | int(11)                                      | NO   | PRI | NULL    |       |
| status      | enum('afwezig','aanwezig','verontschuldigd') | NO   | PRI | afwezig |       |
+-------------+----------------------------------------------+------+-----+---------+-------+

desc persons;
+---------------+----------------+------+-----+-------------------+-----------------------------+
| Field         | Type           | Null | Key | Default           | Extra                       |
+---------------+----------------+------+-----+-------------------+-----------------------------+
| id            | int(11)        | NO   | PRI | NULL              | auto_increment              |
| firstname     | varchar(20)    | YES  |     | NULL              |                             |
| name          | varchar(30)    | YES  |     | NULL              |                             |

+---------------+----------------+------+-----+ -------------------+------------------------------+

我创建了 2 个表单类型 一个用于活动

public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add(
                'start',
                'datetime',
                array(
                    'label' => 'Start'

                )
            )
            ->add(
                'stop',
                'datetime',
                array(
                    'label' => 'Stop'

                )
            )
            ->add('activity', 'text', array('label' => 'Naam'))
            ->add('location', 'text', array('label' => 'Locatie'))
            ->add(
                'presences',
                'collection',
                array(
                    'type' => new PresencesType()
                )
            )
            ->add('save', 'submit', array('label' => 'Aanpassen'));
    }

还有一个用于显示某个活动的存在

  public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add(
                    'persons',
                    'entity',
                    array(
                        'class' => 'KHOSAdminBundle:Persons',
                        'label' => false,
                        'property' => 'fullname',
                        'read_only' => true,
                        'disabled' =>true
                    )
                )
                ->add(
                    'status',
                    'choice',
                    array(
                        'label' => false,
                        'multiple' => false,
                        'expanded' => true,
                        'choices' => array(
                            'afwezig' => 'afwezig',
                            'aanwezig' => 'aanwezig',
                            'verontschuldigd' => 'verontschuldigd'
                        )
                    )
                );
        }

使用 twig 我可以渲染它,以便它显示活动的详细信息并在存在列表下方。

{% for presence in form_activity.presences %}
   <div class="row">
       <div class="col-md-4">
         {{ form_row(presence.persons) }}
       </div>
       <div class="col-md-6">
          {{ form_row(presence.status, { 'style': 'inline' }) }}
       </div>
    </div>
{% endfor %}

然而,所有人都是下拉菜单,加载需要很长时间。 但我不想要那个

我只想要活动的详细信息,并在下面列出所有状态为单选按钮的人

Start: <<inputfield>>   Stop: <<inputfield>>
location: <<inputfield>>

firstname1 name1 : O afwezig  O  aanwezig  O verontschuldigd
firstname2 name2 : O afwezig  O  aanwezig  O verontschuldigd
firstname3 name3 : O afwezig  O  aanwezig  O verontschuldigd
firstname4 name4 : O afwezig  O  aanwezig  O verontschuldigd

有人可以帮我吗?

【问题讨论】:

  • 首先,我想知道为什么每个 Presence 实例都有很多人?通过查看预期的形式,似乎每个 Presence 都只有一个 Person,对吗?加载需要很长时间,因为每个 Presence 实例都会从数据库加载所有 Persons 以创建选择列表(尽管某些缓存机制应该只允许正常执行一次 db 查询,但我没有查看 EntityType 代码而)。
  • 正确:每个presence实例只能有一个人,但每个人可以有多个presence。我将更改实体,使其成为单人关系芯片。您是否也知道如何像我的示例中那样创建一个列表?
  • 好吧,我想我理解这种混淆,entity 字段类型是choice 的子类型,它的目的不是渲染单个实体。我会安排一个可以提供给您的解决方案。

标签: forms symfony collections twig symfony-forms


【解决方案1】:

正如我在评论中建议的那样,您应该使用不使用 entity 字段的自定义类型来表示状态(无论如何,您不希望能够编辑包含在 Presence 实例中的 Person ,这意味着您不'不想要 firstName 和 lastName 字段)。

这是php部分:

<?php

namespace Demo {
    class Activity
    {
        protected $id;
        protected $start;
        protected $stop;

        /** @var Presence[] */
        protected $presences = [];

        // ...
    }

    class Presence {
        /** @var Activity */
        protected $activity;
        /** @var Person */
        protected $person;
        protected $status;

        // ...
    }

    class Person {
        protected $firstName;
        protected $lastName;
        /** @var Presence[] */
        protected $presences;

        // ...
    }

    class ActivityType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add('start')
                ->add('stop')
                ->add('location')
                ->add('presences', 'collection', [
                    'type' => new PresenceType(),
                ])
            ;
        }

        public function getName()
        {
            return 'activity';
        }
    }

    class PresenceType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add('status', 'choice', [
                    'multiple' => true,
                    'expanded' => false,
                    'choices' => [
                        'afwezig' => 'afwezig',
                        'aanwezig' => 'aanwezig',
                        'verontschuldigd' => 'verontschuldigd'
                    ]
                ])
            ;
        }

        public function getName()
        {
            return 'presence';
        }
    }
}

还有 twig 表单主题(它可能需要一些调整才能真正起作用,但其想法是定义当您调用 form_row(form) 并且 form 是 PresenceType 视图实例时呈现表单视图的呈现方式):

{% block presence_row %}
    {{ form.vars.data.user.firstName }} {{ form.vars.data.user.lastName }} {{ form_widget(form) }}
    # form.vars.data contains the Presence instance
{% endblock %}

如您所见,我使用表单主题来显示 Person 的 firstName 和 lastName,我还没有将它添加到我的 PresenceType 类中,这是因为我不需要 firstName 和 lastName 输入字段。

【讨论】:

  • 我明白你在说什么,但我无法让它发挥作用。我无法获取表单中的名字和姓氏,并且表单是 PresenceTypeView 实例。错误总是在那种
  • 我明白你在说什么,但我无法让它发挥作用。我无法获取表单中的名字和姓氏,并且表单是 PresenceTypeView 实例。错误总是出现在以下类型中:对象“Symfony\Component\Form\FormView”的方法“......”不存在于......我的树枝 {{ form_start(form_activity) }} {{ form_row (form_activity.start) }} ..... {{ form_row(form_activity.save) }} {% for presence in form_activity.presences %} {{ presence.user.data.firstname }} {{ form_row(presence.status ) }} {% endfor %}
  • presence.user 不起作用,因为 PresenceType 没有 user 字段。您必须使用底层 Presence 对象:presence.vars.data.user.firstName,(presence.vars.data 是 Presence 对象)。
  • 吉尔达斯,你让我很开心。非常感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-01
  • 1970-01-01
  • 2017-10-18
  • 1970-01-01
  • 2022-01-28
  • 2021-02-22
  • 1970-01-01
相关资源
最近更新 更多