【问题标题】:Symfony2 - how to create form based on dynamic parameters from db? (EAV)Symfony2 - 如何根据数据库中的动态参数创建表单? (EAV)
【发布时间】:2011-11-11 02:25:59
【问题描述】:

我想根据存储在数据库中的动态参数创建表单。 所以我创建了一个名为 Parameter 的实体,它定义了参数名称,它应该显示为表单字段标签。

/**
 * @ORM\Entity
 */
class Parameter
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
    /**
     * @ORM\Column(type="string", length="255")
     * @Assert\NotBlank()
     */
    protected $name; 
    /**
     * @ORM\OneToMany(targetEntity="ParameterValue", mappedBy="parameter")
     */
    protected $values;

特定对象(公司对象)的参数值即将存储在 ParameterValue 表中。

/**
 * @ORM\Entity
 */
class ParameterValue
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
    /**
     * @ORM\ManyToOne(targetEntity="Parameter", inversedBy="values")
     * @ORM\JoinColumn(name="parameter_id", referencedColumnName="id", nullable=false)
     */
    protected $parameter;
    /**
     * @ORM\ManyToOne(targetEntity="Company", inversedBy="parameters")
     * @ORM\JoinColumn(name="company_id", referencedColumnName="id", nullable=false)
     */
    protected $company;

当然,公司实体包含参数属性,该属性仅存储为公司指定的那些参数。

/**
 * @ORM\Entity
 */
class Company
{    
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
    /**
     * @ORM\Column(type="string", length="255")
     */
    protected $name;
    /**
     * @ORM\OneToMany(targetEntity="ParameterValue", mappedBy="hotel")
     */
    protected $parameters;

如何创建从 DB 动态获取所有参数、创建具有特定标签 (label=Parameter->getName()) 的文本字段并获取已与 Company 关联的参数的 ParameterValues 的表单(用于编辑操作)?

我已经创建了获取 ParameterValues 的“集合”字段,但问题是我得到的表单包含已用于公司但没有其他参数的字段。当然我不能得到标签,因为集合字段类型是 ParameterType 而不是 Parameter。

【问题讨论】:

    标签: forms symfony entity-attribute-value


    【解决方案1】:

    我最近不得不做类似的事情。我将分享我的经验并尝试结合您的观点。您可能需要对其进行一些修改以满足您的需要。

    我的公司实体与您的实体相似。我希望每个存储的公司都有与其相关联的动态数量的参数和值,并且能够使用 symfony2 表单框架在表单中编辑这些。

    我首先创建了一个名为 CompanyParameter 的实体。添加命名空间并保存在包中的某个位置。

        class CompanyParameter {    
            protected $data;    
            public function __construct($parameters,$edit=false)
            {
                   if ($edit==false) {
                    foreach ($parameters as $k => $value) {
                            $name = $value->getId();
                            $this->data[$name] = array("label"=>$value->getName(),"value"=>"");
                            $this->{$name} = "";                    
                    }
                    } else {
                    foreach ($parameters as $k => $value) {
                            $name = $value->getParameterid();
                            $pvalue = $value->getValue();
                            $this->data[$name] = array("label"=>$value->getName(),"value"=>$pvalue);
                            $this->{$name} = $pvalue;                    
                    }
    }
            }    
            public function get() { return $this->data; }    
        }
    

    使用该类创建一个新变量并将您的参数发送给它。

    $parameters = $em->getRepository("YourBundle:Parameter")->findAll();
    $companyparameter = new CompanyParameter($parameters);
    

    您现在拥有一个包含您要管理的所有动态参数的实体。 (如果您想加载已存储值的 CompanyParameter 以进行编辑,只需向 CompanyParameter 发送一个 ParameterValue 实体数组,并在构造函数中设置 $edit=true。

    创建一个 CompanyParameterFormType,如http://symfony.com/doc/current/book/forms.html#creating-form-classes 中所述 确保 data_class 指向 CompanyParameter

    在您的控制器中创建一个新表单:

    $form = $this->createForm(new CompanyParameterTypeBundle(), $companyparameter);
    

    CompanyParameterFormType 内部:

        public function buildForm(FormBuilder $builder, array $options)
        {
            $data = $options["data"]->get();      
            foreach ($data as $k => $value) {
                 $builder->add($k,"text",array("label"=>$value["label"]));
            }           
        }
    

    如果我们使用 $form->createView(),我们现在将拥有一个包含“公司名称”和“CEO”两个字段的表单。

    填写表单并将表单的提交发送回相同的操作。

    在 post 和 $form->bindRequest($this->getRequest()) 的动作检查中。

    CompanyParameter 现在包含属于当前公司的所有参数值。持久化这些数据:

    $data = $companyparameter->get();
    $counter = 0;
    foreach($data as $k => $value) {
    $parameter = new ParameterValue();
    $parameter->setCompany($company);
    $parameter->setParameter($parameters[$counter]);
    $parameter->setValue($value["value"]);
    $em->persist($parameter);
    $counter++;
    }
    

    如果您改为编辑参数

    $data = $companyparameter->get();
    foreach ($parameters as $k => $value) {
    $value->setValue($data[$value->getParameterid()]["value"]);
    $em->persist($value);
    }
    

    希望这会有所帮助。我第一次发帖,我还不太习惯“解释”代码,所以请记住。

    【讨论】:

    • 我已经尝试了您的建议,但有一个错误:您正在从CompanyParameter$data 数组($data[$value->getParameterid()]["value"])读取绑定的表单数据,但是它没有写在那里。您必须改为从$companyparameter->{$value->getParameterid()} 获取它。 (顺便说一句,你并没有真正定义 getParameterid() 是什么,但我明白了......)
    猜你喜欢
    • 2015-07-19
    • 1970-01-01
    • 2016-07-23
    • 2013-11-12
    • 1970-01-01
    • 2019-09-29
    • 1970-01-01
    • 1970-01-01
    • 2020-02-01
    相关资源
    最近更新 更多