2014-10-01 51 views
1

我正在尝试做一些我不确定是否可以执行的操作。Symfony 2:绑定请求以形成包含对象的对象

这里是我的表单对象:

class DeclarationForm { 
    private $string1; 
    private $paramObject; 
} 

这里是param对象:

class Param { 
    private $id; 
    private $name; 
} 

我想在创建阶段显示选择的“ParamObject”字段的形式

public function buildForm(FormBuilderInterface $builder, array $options) { 
    $phase = intval($this->options['phase']); 

    if($phase === 0) { 
     $params_qualities = $this->options['params_qualities'] // this is an array of Param Objects; 
     $qualities = new ObjectChoiceList($params_qualities, 'name', array(), null, 'id'); 
     $builder->add('paramObject', 'choice', array(
      'required' => true, 
      'choice_list' => $qualities 
     )); 
    } 
    ... 
} 

它工作正常,当然,当我提交表单时,只有所选选项的ID被放入请求。 问题是当我使用$ form-> handleRequest($ request);在控制器中,它会尝试将一个字符串(id值)放入我的DeclarationForm的Param对象中。

当handleRequest尝试将请求绑定到对象时,甚至有可能在请求中填充Param对象的选定选项的标签?

如何做到这一点?

谢谢

回答

0

这是可能的,但不是只有一个窗体。在Symfony中,每个单独的Form都有一个单独的备份数据对象(如果有的话),并且每个HTML字段对应于该对象的单个成员(除了日期和实体等特殊情况外)。但是,one of the Field Types you can use is Form,表示具有其自己的数据对象的子Form。

在你的情况,这意味着做这样的事情:在

public parameterAction() { 
    //Get param options somehow and stick in $options 

    $paramForm = $this->createForm(new DecorationFormType(), $decorationForm, $options); 
} 

所以基本上你创建你的主要形态是正常的控制器

class DecorationFormType { 

    public function buildForm(FormBuilderInterface $builder, array $options) { 
     $phase = intval($this->options['phase']); 

     if($phase === 0) { 
      //Add child form for param; pass options (with dropdown info) in 
      //By default fieldname needs to match object member 
      $builder->add('paramObject', new ParamType(), ['options' => $options]); 
     } 
     ... 
    } 
} 

class ParamType { 

    public function buildForm(FormBuilderInterface $builder, array $options) { 

      $params_qualities = $this->options['params_qualities'] // this is an array of Param Objects; 
      $qualities = new ObjectChoiceList($params_qualities, 'name', array(), null, 'id'); 
      //By default fieldname needs to match object member 
      $builder->add('id', 'choice', array(
       'required' => true, 
       'choice_list' => $qualities 
      )); 
     ... 
    } 

} 

然后,在这种形式的一个它添加的字段是子窗体。该Field的名称需要与DeclarationForm类上的公共属性或getter相匹配,以便它可以找到数据对象(可以在选项中覆盖该属性)。您在每个表单上适当地设置了data_class。如果那不太合适,我没有测试它,我更习惯于使用集合(这是根据数据可能存在几个给定子表单的地方)的道歉。

一般来说,建议是使用Form Events来操纵字段被添加到表单中(例如,如果您的参数只有phase==0),但是我认为这不重要,如果您只打算使用表单一旦。

我通常不会使用表单选项将下拉信息传递给表单,但那可能只是我,不知道最佳做法是什么 - 一方面,您将自己的东西混合带有固定Symfony键的整个负载,但另一方面它是一个方便的地方!我过去曾使用过我的数据对象的成员。

至于你从HTML表单获取标签的问题 - 你不能这样做,因为正如你所见,请求包含的唯一东西就是ID。我能想象解决这个几种方法:在参数对象

  • 使用标签作为下拉键(如果他们是唯一的)
  • 重新映射到的ID标签弄好了,给它的选项列表中,这样你的时候去getName()或任何它可以神奇地给你想要的东西
  • 只要接受,你得到一个ID回来,看看它的意思,当你使用它!