2014-10-01 53 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回來,看看它的意思,當你使用它!