【问题标题】:Symfony2 save embedding collection formSymfony2 保存嵌入集合表单
【发布时间】:2023-03-10 23:46:01
【问题描述】:

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

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个级别。

例如我想将program name 保存为English,然后添加3 个级别(basic、intermediate、advanced)。成功保存到数据库的级别只有第一个级别(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;
    }
}

【问题讨论】:

    标签: php jquery forms symfony


    【解决方案1】:

    检查是否将 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;
        }
    

    【讨论】:

    • 这对我有一点帮助。我已经声明了addLevels 函数,但是我忘记在我的program 实体中声明setLevels 函数。它可以帮助我保存与关卡相关的程序名称。还是同样的问题,只保存了第一个和最后一个级别,数据库中只保存了2个级别。
    • 然后检查是否在Level类中声明了setProgram方法
    • 检查我的更新。我已经声明了那个方法。仍然不能超过2级。我是否需要创建一个循环并检查有多少级别的表单字段具有值?如果我必须这样做,我应该在哪里添加循环条件?
    • 您可以在 setLevel 中添加一个计数器或使用 count($form->getData()->getLevel()) 检入您的控制器
    • 也许我在构建表单时出错了,因为当我count($form-&gt;getData()-&gt;getLevel()) 时,它返回2。我预计会返回3。
    【解决方案2】:

    从控制器中删除此代码

     $level = new Level();
    
        $program->getLevels()->add($level);
    

    【讨论】:

    • 如果我删除这些代码,我只能保存 1 个级别。也许我必须做一个循环,但我无法获得表单字段的级别数。
    【解决方案3】:

    您在实体程序中的 getter 和 setter $levels 混淆了...

    制作:

    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-&gt;getLevels()-&gt;add($level); 也没有意义。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多