Symfony2保存嵌入集合表单

时间:2014-04-23 08:10:21

标签: php jquery forms symfony

我遇到了保存嵌入式收集表单字段的问题。假设我有程序,程序有很多级别。在我的表单中输入:

ProgramType.php

<?php

namespace Eifl\AdminBundle\Form\Type;

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

class ProgramType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('id','text',array(
                'label'=>'Program Code',
            ))
            ->add('program','text',array(
                'label'=>'Program Name',
            ))
            ->add('levels','collection', array(
                'type'=>new LevelType(),
                'allow_add'=>true,
                'allow_delete'=>true,
                'by_reference' => false,
            ))
            ->add('save','submit', array(
                'label'=>'Save',
            ));
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Eifl\AdminBundle\Entity\Program',
        ));
    }

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

LevelType.php

<?php

namespace Eifl\AdminBundle\Form\Type;

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

class LevelType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('level','text',array(
            'label'=>'Level Name',
        ));
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Eifl\AdminBundle\Entity\Level',
        ));
    }

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

我根据this link的教程制作了可以使用jquery添加新集合level字段的表单,我的表单结果与此link中的图片相同

现在我的问题是我无法保存超过2个级别。收集表格只保存2个级别。

e.g。我想将program name保存为English,之后我添加3个级别(basicintermediateadvanced)。成功保存到数据库的级别仅为第一级(basic)和最后一级(Advanced)。我想要的是将所有级别保存到数据库。任何人都可以帮助我吗?

此外,这是我的控制器的一部分:

DefaultController.php

public function programAction(Request $request)
{
    $program = new Program();
    $level = new Level();

    $program->getLevels()->add($level);
    $newProgram = $this->createForm(new ProgramType(),$program);
    $newProgram->handleRequest($request);

    if($newProgram->isValid()){
        $em = $this->getDoctrine()->getManager();
        $em->persist($program);
        $em->flush();

        return $this->redirect($this->generateUrl('eifl_admin_program'));
    }
    return $this->render('EiflAdminBundle:Default:program.html.twig',array("new_program_form"=>$newProgram->createView()));
}

更新

这是我的实体类。

Program.php

<?php

namespace Eifl\AdminBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * Program
 *
 * @ORM\Entity
 * @ORM\Table(name="tbl_program")
 */
Class Program
{
    /**
     * @ORM\Id
     * @ORM\Column(name="id", type="string")
     */
    protected $id;

    /**
     *@ORM\Column(name="program_name",type="string")
     */
    public $program;

    /**
     * @ORM\OneToMany(targetEntity="Eifl\AdminBundle\Entity\Level", mappedBy="program", cascade={"remove","persist"})
     */
    public $levels;

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

    /**
     * @param string $id
     * @return string
     */
    public function setId($id)
    {
        $this->id = $id;

        return $this;
    }

    /**
     * Add Level
     *
     * @param \Eifl\AdminBundle\Entity\Level $levels
     * @return Program
     */
    public function addLevels(\Eifl\AdminBundle\Entity\Level $level) {
        $this->levels[] = $level;
        $levels->setProgram($this);

        return $this;
    }

    /**
     * set levels
     *
     * @param \Doctrine\Common\Collections\ArrayCollection $levels
     * @return levels
     */
    public function setLevels(\Doctrine\Common\Collections\ArrayCollection $levels) {
        foreach ($levels as $level) {
            $level->setProgram($this);
        }
        $this->levels = $levels;
    }

    public function removeLevels(\Eifl\AdminBundle\Entity\Level $level)
    {
        $this->levels->removeElement($level);
    }

    /**
     * @param string $program
     * @return string
     */
    public function setProgram($program)
    {
        $this->program = $program;

        return $this;
    }

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

    /**
     * @return string
     */
    public function getProgram()
    {
       return $this->program;
    }

    /**
     * @return string
     */
    public function getLevels()
    {
       return $this->levels;
    }
}

Level.php

<?php

namespace Eifl\AdminBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Level
 *
 * @ORM\Entity
 * @ORM\Table(name="tbl_level")
 */
Class Level
{
    /**
     * @ORM\Id
     * @ORM\Column(name="id", type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     *@ORM\Column(name="level",type="string")
     */
    public $level;

    /**
     * @ORM\ManyToOne(targetEntity="Eifl\AdminBundle\Entity\Program", inversedBy="levels")
     * @ORM\JoinColumn(name="program", referencedColumnName="id")
     */
    public $program;

    /**
     * @param string $id
     * @return string
     */
    public function setId($id)
    {
        $this->id = $id;

        return $this;
    }

    /**
     * @param string $level
     * @return string
     */
    public function setLevel($level)
    {
        $this->level = $level;

        return $this;
    }

    /**
     * @param mixed $program
     * @return string
     */
    public function setProgram(\Eifl\AdminBundle\Entity\Program $program)
    {
        $this->program = $program;

        return $this;
    }

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

    /**
     * @return string
     */
    public function getLevel()
    {
        return $this->level;
    }

    /**
     * @return string
     */
    public function getProgram()
    {
        return $this->program;
    }
}

3 个答案:

答案 0 :(得分:0)

检查是否在程序实体中添加了addLevel和setLevel

     /**
     * Add Level
     *
     * @param \Eifl\AdminBundle\Entity\Level $levels
     * @return Program
     */
    public function addLevel(\Eifl\AdminBundle\Entity\Level $levels) {
        $this->levels[] = $levles;

        $level->setProgram($this);

        return $this;
    }

    /**
     * set levels
     *
     * @param \Doctrine\Common\Collections\ArrayCollection $levels
     * @return levels
     */
    public function setLevels(\Doctrine\Common\Collections\ArrayCollection $levels) {
        foreach ($levles as $level) {
            $level->setPogram($this);
        }
        $this->levels = $levels;
    }

答案 1 :(得分:0)

从控制器中删除此代码

 $level = new Level();

    $program->getLevels()->add($level);

答案 2 :(得分:0)

实体计划中的getter和setter $级别很混乱......

制作:

public function addLevel(Level $level) { //without s
  $this->levels[] = $level;
}
public function removeLevel(Level $level) //without s
{
    $this->levels->removeElement($level);  
}
public function getLevels()
{
   return $this->levels;
}

删除其他人public function setLevels, public function removeLevels, etc

就像Adene Choubi所说,$program->getLevels()->add($level);也没有意义。

不知道它是否是唯一的麻烦,但从此开始。