如何使用Silex和Symfony Forms以嵌入形式显示嵌入对象的数据?

时间:2016-03-03 08:39:31

标签: php forms symfony silex

我的应用程序中有一个名为Content的模型。这有三个属性链接到另一个名为ContentBodyType的模型。这是为了允许内容的三个部分,即“横幅”,“摘要”和“主要”。

我使用SymfonyForms为FormType模型创建了Content。以下显示了如何构建它:

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

    $list = $this -> app['model.collection'] -> getList();

    $builder -> add('id', HiddenType::Class)
             -> add('displayname', TextType::Class, array("label" => "Friendly Name", "trim" => true))
             -> add('description', TextareaType::Class)
             -> add('collection', ChoiceType::Class, array(
               'choices_as_values' => true,
               "choices" => $list,
               "label" => "Collection"
             ))
             -> add('publish', ChoiceType::Class, array(
               "choices" => array('Yes' => true, 'No' => false),
               "choices_as_values" => true,
               "expanded" => true,
               "multiple" => false,
             ))
             -> add('homepage', ChoiceType::Class, array(
               "choices" => array('Yes' => true, 'No' => false),
               "choices_as_values" => true,
               "expanded" => true,
               "multiple" => false,
             ))
             -> add('startdate', DateTimeType::Class, array("widget" => "single_text", "format" => "dd-MM-yyyy"))
             -> add('expirydate', DateTimeType::Class, array("widget" => "single_text", "format" => "dd-MM-yyyy"))
             -> add('type', ChoiceType::Class, array(
               "choices_as_values" => true,
               "choices" => array(
                 'News' => "news",
                 'Page' => "page",
                 'Pinned' => "pinned",
                 'Blog' => "blog",
                 'Slider' => "slider"
               ),
               "label" => "Type"
             ))
             -> add('main', new \Turtle\Form\Type\ContentBodyType())
             -> add('banner', new \Turtle\Form\Type\ContentBodyType())
             -> add('summary', new \Turtle\Form\Type\ContentBodyType())
             -> add('save', SubmitType::Class)
             -> add('cancel', ButtonType::Class);

    // only add the name field if this is a new template
    if (!$this -> content || null == $this -> content -> getId()) {
      $builder -> add('name', TextType::Class, array('label' => 'Name'));
    }
  }

当应用程序加载表单时,它会在正确的字段中显示Content模型中的数据,但不会显示嵌套表单中的数据。

现在我知道这是因为对于'banner','summary'和'main'中的每一个,我都在创建ContentBodyType表单对象的新实例。但是我无法弄清楚如何将对象传递给它,以便不必创建它。

使用以下代码创建表单:

   public function edit(Request $request, $id) {

     // Get the entity from the datastore for the specified id
     if ($id == "new") {
       $item = new \Turtle\Model\Entity\Content(); 
     } else {
       $item = $this -> app['model.content'] -> getById($id) -> first();
     }

     if (!$item) {
       return "notthere";
     }

     // Build the form
     $type = new \Turtle\Form\Type\ContentType($this -> app, $item);

     $form = $this -> app['form.factory'] 
                   -> createBuilder(
                         $type, 
                         $item, 
                         array(
                           'action' => $this -> app['url_generator'] -> generate(
                             'content_update', 
                             array(
                               'id' => $item -> getId()
                             )
                           )
                         )
                       ) -> getForm();

     // process the form to see if it has been submitted or not
     $form -> handleRequest($request);

     snip ....

我确信这是一个简单的修复,但我看不出它是什么。

谢谢,拉塞尔

1 个答案:

答案 0 :(得分:0)

我已经解决了这个问题。我忘记了当我创建ContentBody的实例时,我使构造函数接受了参数,其中一个参数是从数据存储区加载的项目。

class ContentType extends AbstractType {

  private $app;
  private $item;

  public function __construct($app, $item) {
    $this -> app = $app;
    $this -> item = $item;
  }

  snip....

因为我将该项作为类中的属性,然后我可以将其传递给ContentBodyType函数中的buildForm。所以现在创建表单的三个部分:

-> add('main', new \Turtle\Form\Type\ContentBodyType($this -> item -> getBanner()))
-> add('banner', new \Turtle\Form\Type\ContentBodyType($this -> item -> getSummary()))
-> add('summary', new \Turtle\Form\Type\ContentBodyType($this -> item -> getMain()))

我不确定这是否是正确的方法,因为我确信在SymfonyForms代码中某些时候模型会传递给FormType,但这解决了我遇到的问题。