简体   繁体   English

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

[英]How do I display data for an embedded object in an embedded form using Silex and Symfony Forms?

I have a model in my application called Content . 我的应用程序中有一个名为Content的模型。 This has three properties that are linked to another model called ContentBodyType . 它具有三个属性,这些属性链接到另一个名为ContentBodyType模型。 This is to allow three sections of the content which are 'Banner', 'Summary' and 'Main'. 这是为了允许内容的三个部分,分别是“横幅”,“摘要”和“主要”。

I have created a FormType for the Content model using SymfonyForms. 我已经使用SymfonyForms为Content模型创建了一个FormType The following shows how this is built up: 下面显示了它是如何构建的:

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'));
    }
  }

When the application loads up the form it shows the data from Content model in the correct fields, however the ones that are part of the nested form are not displayed. 当应用程序加载表单时,它将在正确的字段中显示Content模型中的数据,但是不会显示嵌套表单中的数据。

Now I know that this is because for each of 'banner', 'summary' and 'main' I am creating a new instance of the ContentBodyType form object. 现在,我知道这是因为对于“横幅”,“摘要”和“主”中的每一个,我都在创建ContentBodyType表单对象的新实例。 However I cannot work out how to pass in the object to this so that it does not have to be created. 但是,我无法解决如何将对象传递给此对象,从而不必创建它。

The form is created using the following code: 该表单是使用以下代码创建的:

   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 ....

I am sure that this is a simple fix, but I just cannot see what it is. 我确信这是一个简单的修复程序,但我只是看不到它是什么。

Thanks, Russell 谢谢,罗素

I have worked this out. 我已经解决了。 I had forgotten that when I create an instance of the ContentBody I made the constructor accept arguments one of which was the item that had been loaded from the datastore. 我已经忘记了,当我创建ContentBody的实例时,我让构造函数接受了参数,其中之一就是从数据存储区加载的项目。

class ContentType extends AbstractType {

  private $app;
  private $item;

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

  snip....

So as I have the item as a property in the class, I can then pass this to the ContentBodyType in the buildForm function. 因此,由于我将该项目作为类的属性,因此可以将其传递给buildForm函数中的ContentBodyType So now the three sections of the form get created thus: 因此,现在可以创建表单的三个部分:

-> 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()))

I am not sure if this is the correct way to do it because I am sure that at some point in the SymfonyForms code the model is passed to the FormType, but this solved the issue I had. 我不确定这是否是正确的方法,因为我确定在SymfonyForms代码中的某个时刻模型会传递给FormType,但这解决了我遇到的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM