@HunteX

Как реализовать массовое представление/редактирование сущностей на одной форме?

Доброго времени суток.
Начал изучать symfony2 framework и столкнулся с проблемой.
Вообщем, имеется такая сущность (что-то вроде расширенного справочника):

/**
 * Ns\TestBundle\Entity\Config
 *
 * @ORM\Table(name="configs")
 * @ORM\Entity()
 */
class Config
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=100)
     */
    private $name;

    /**
     * @ORM\Column(type="string", length=200)
     */
    private $value;

    /**
     * @ORM\Column(type="string", length=100)
     */
    private $description;
}


Необходимо получить из базы все эти объекты типа Config и представить на страничке в одной форме, для их массового редактирования.

Как это реализовать? Какими должны быть Controller Actions/FormType/Twig Template?

Если у Вас есть какой-то иной вариант для решения моей проблемы, буду рад его узнать.
  • Вопрос задан
  • 2688 просмотров
Решения вопроса 1
silentvick
@silentvick
Создайте оберточную форму и встраивайте в нее сколько угодно форм сущностей
How to Embed a Collection of Forms

Например...

1. Создаем класс, который будет просто держать коллекцию нужных нам сущностей. Для примера, назову его ConfigHolder.
namespace Ns\TestBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;

class ConfigHolder
{
    protected $_configs;

    public function getConfigs()
    {
        if ( is_null($this->_configs) ) {
            $this->_configs = new ArrayCollection();
        }

        return $this->_configs;
    }

    public function setConfigs(ArrayCollection $configs)
    {
        $this->_configs = $configs;
    }
}

2. Создадим форму для этого класса. Можно, конечно, было обойтись без отдельного класса, но мне кажется, так код будет немного чище. В конструкторе формы добавляем поле типа collection, и указываем тип встраиваемых полей - ConfigType (класс формы для Config; его создание тривиально, поэтому я буду исходить из того, что он уже написан)
namespace Ns\TestBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class ConfigHolderType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('configs', 'collection', array('type' => new ConfigType()));
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Ns\TestBundle\Entity\ConfigHolder',
        ));
    }

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

3. Осталось дело за малым. Всего сотня-другая строчек кода... :) Теперь, когда есть все необходимое можно создать форму в контроллере и работать с ней, как и со всеми остальными формами. Например:
namespace Acme\TaskBundle\Controller;

use Ns\TestBundle\Entity\ConfigHolder;
use Ns\TestBundle\Entity\Config;
use Ns\TestBundle\Form\Type\ConfigHolderType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Doctrine\Common\Collections\ArrayCollection;

class ConfigHolderController extends Controller
{
    public function editAction(Request $request)
    {
        // Подгружаем нужные конфиги из базы, получая массив объектов
        // $configs = ...

        $configHolder = new ConfigHolder();
        $configHolder->setConfigs(new ArrayCollection($configs));

        $form = $this->createForm(new ConfigHolderType(), $configHolder);
        $form->handleRequest($request);

        if ( $form->isValid() )
        {
            // получили данные и делаем с ними все, что захотим,
            // можно, например, в базу данных сохранить...
        }

        return $this->render('NsTestBundle:ConfigHolder:edit.html.twig', array(
            'form' => $form->createView(),
        ));
    }
}

4. Остался вывод формы. Здесь нужно лишь пройтись в цикле по вложенным формам.
{# src/Ns/TestBundle/Resources/views/ConfigHolder/edit.html.twig #}

{{ form_start(form) }}
    {% for config in form.configs %}
        <div>
            {{ form_row(config.name) }}
        </div>
        <div>
            {{ form_row(config.value) }}
        </div>
        <div>
            {{ form_row(config.description) }}
        </div>
    {% endfor %}
{{ form_end(form) }}

Код писал «на глаз», возможны ошибки, но суть, надеюсь, передана.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы