簡體   English   中英

堅持表格數據Symfony 2.8

[英]Persist form data Symfony 2.8

我是Symfony的新手,並且遵循此文檔http://symfony.com/doc/current/cookbook/form/form_collections.html來構建基本的嵌入收集表單。

請遵循文檔。 我們有標簽和任務。 Task與Tag具有oneToMany關系,而Tag與Task具有ManyToOne關系。

我還將TaskType中的EntityType :: class與queryBuilder一起使用,以在表單上的數據庫中預先填充現有Task實體的選擇列表。

我已經完成了構建表格,一切正常。 但是,當我提交表單而不使用現有的“任務ID”時,會生成一個具有新ID但具有相同數據的新任務。 該新任務ID被分配給新的標簽實體。 我想將現有的任務ID用於新標簽。

以下是我的YAML文件類:

TaskController.php

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use AppBundle\Entity\Task;
use AppBundle\Entity\Tag;
use AppBundle\Form\Type\TaskType;


class TaskController extends Controller
{
    public function newAction(Request $request)
    {
        $task = new Task();

        // dummy code - this is here just so that the Task has some tags
        // otherwise, this isn't an interesting example
        $tag1 = new Tag();
        $tag1->setName('tag1');

        $tag1->addTask($task);
        $task->getTags()->add($tag1);


        $form = $this->createForm(TaskType::class, $task);

        $form->handleRequest($request);

        if ($form->isValid()) {


            $em = $this->getDoctrine()->getManager();
            $em->persist($task);
            $em->flush();
        }

        return $this->render('AppBundle:Task:new.html.twig', array(
            'form' => $form->createView(),
        ));

    }

}

Tag.php

namespace AppBundle\Entity;

/**
 * Tag
 */
class Tag
{
    /**
     * @var integer
     */
    private $id;

    /**
     * @var string
     */
    private $name;


    /**
     * @var \AppBundle\Entity\Task
     */
    private $task;


    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     *
     * @return Tag
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }


    /**
     * Set task
     *
     * @param \AppBundle\Entity\Task $task
     *
     * @return Tag
     */
    public function setTask(\AppBundle\Entity\Task $task = null)
    {
        $this->task = $task;

        return $this;
    }

    /**
     * Get task
     *
     * @return \AppBundle\Entity\Task
     */
    public function getTask()
    {
        return $this->task;
    }


    public function addTask(Task $task)
    {

        $this->setTask($task);
    }
}

TagType.php

namespace AppBundle\Form\Type;

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



class TagType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('name');
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\Tag',
        ));
    }

}

標記文件

AppBundle\Entity\Tag:
    type: entity
    table: null
    repositoryClass: AppBundle\Repository\TagRepository
    id:
        id:
            type: integer
            id: true
            generator:
                strategy: AUTO
    fields:
        name:
            type: string
            length: 255

    manyToOne:
        task:
            targetEntity: Task
            inversedBy: tags
            joinColumn:
                name: task_id
                referencedColumnName: id
            cascade: [ persist ]


    lifecycleCallbacks: {  }

Task.php

namespace AppBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;

/**
 * Task
 */
class Task
{
    /**
     * @var integer
     */
    private $id;

    /**
     * @var string
     */
    private $description;

    /**
     * @var ArrayCollection
     */
    protected $tags;


    public function __construct()
    {
        $this->tags = new ArrayCollection();
    }

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set description
     *
     * @param string $description
     *
     * @return Task
     */
    public function setDescription($description)
    {
        $this->description = $description;

        return $this;
    }

    /**
     * Get description
     *
     * @return string
     */
    public function getDescription()
    {
        return $this->description;
    }

    /**
     * Get tags
     *
     * @return ArrayCollection
     */
    public function getTags()
    {
        return $this->tags;
    }

    public function addTag(Tag $tag)
    {
        $tag->addTask($this);
        $this->tags->add($tag);
    }


    /**
     * Remove tag
     *
     * @param \AppBundle\Entity\Tag $tag
     */
    public function removeTag(\AppBundle\Entity\Tag $tag)
    {
        $this->tags->removeElement($tag);
    }


    public function __toString()
    {
       return (string) $this->getDescription();
    }


}

TaskType.php

namespace AppBundle\Form\Type;


use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Doctrine\ORM\EntityRepository;



class TaskType extends AbstractType
{
    function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('description', EntityType::class,array(
            'class' => 'AppBundle:Task',
            'query_builder' => function (EntityRepository $er) {
                return $er->createQueryBuilder('d');
            },));

        $builder->add('tags', CollectionType::class, array(
            'entry_type' => TagType::class,
            'allow_add'    => true,
            'by_reference' => false,
        ));

        $builder->add('save', SubmitType::class, array('label' => 'Save'));

    }


    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\Task',
        ));
    }

}

Task.orm.yaml

AppBundle\Entity\Task:
    type: entity
    table: null
    repositoryClass: AppBundle\Repository\TaskRepository
    id:
        id:
            type: integer
            id: true
            generator:
                strategy: AUTO
    fields:
        description:
            type: string
            length: 255

    oneToMany:
        tags:
          targetEntity: Tag
          mappedBy: task
          cascade: [ persist ]

    lifecycleCallbacks: {  }

哦,我明白了。 提交表單(並保存帶有標簽的新任務)時,將顯示相同的表單,因此用戶希望它是“編輯”表單,但事實並非如此。

正確的方法是創建新的控制器動作來編輯任務,例如editAction() ,它類似於newAction() ,只是路由將具有用於標識任務的參數(例如task_id ),並且首先不要用$task = new Task();創建新Task $task = new Task(); 您可以從數據庫中獲取任務,例如:

$task = $this->get("doctrine")->getManager()->getRepository("AppBundle:Task")->findOneById($task_id);

您也可以重復使用相同的表單類型。

然后 ,您將實體保留到此新的編輯操作后,在原始newAction中添加重定向:

return $this->redirectToRoute("task_edit", array("task_id" => $task->getId()));

因此,在提交添加表單后,您將被重定向到編輯操作,因此下次更改任務並提交時,該任務將更新而不創建新任務。

因此,我需要做的是使用$ form-> getData()獲取提交的實體(任務和標簽),然后將其手動保存到數據庫中。

   if ($form->isValid()) {
        $data = $form->getData();

        $description = $data->getDescription();

        $tags = new ArrayCollection();

        $tags = $data->getTags();

        foreach ($tags as $tag) {
            $tag->addTask($description);
        }


        $em = $this->getDoctrine()->getManager();
        $em->persist($tag);
        $em->flush();
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM