【问题标题】:Symfony 2 Form, field collection doesn't displaySymfony 2 Form,字段集合不显示
【发布时间】:2011-12-01 00:31:06
【问题描述】:

我想创建一个可以添加多个 etape 的表单。我创建这样的表单:

//形式

 namespace RBO\TryBundle\Form\Type;

 use Symfony\Component\Form\AbstractType;
 use Symfony\Component\Form\FormBuilder;

 use RBO\TryBundle\Entity\Try;

 class TryType extends AbstractType {
   public function buildForm(FormBuilder $builder, array $options)
   {
     $builder->add('etapes', 'collection', array(
        'type' => new EtapeType(), 
        'allow_add' => true,
        'allow_delete' => true,
        'prototype' => true,
        'label' => 'Etapes'
    ));
  }
  public function getName()
{
    return 'try';
}

public function getDefaultOptions(array $options)
{
    return array(
        'data_class' => 'RBO\TryBundle\Entity\Try',
        'csrf_protection' => true,
        'csrf_field_name' => '_token',
        // a unique key to help generate the secret token
        'intention'       => 'try_item',
    );
}
 }

// EtapeType

<?php

namespace RBO\TryBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;

use RBO\TryBundle\Entity\Etape;

class EtapeType extends AbstractType {

public function buildForm(FormBuilder $builder, array $options)
{
    $builder->add('name', 'text');
}

public function getDefaultOptions(array $options)
{
    return array(
        'data_class' => 'RBO\TryBundle\Entity\Etape',
    );
}

public function getName()
{
    return 'etape';
}

}

// 在树枝模板中显示

{{ form_row(form.etapes) }}

实体 Try 有一个属性 etapes,它是一个 ArrayCollection(在构造函数中定义)

此代码不会渲染任何期望的标签。我错过了什么吗?

提前谢谢你

【问题讨论】:

    标签: forms collections symfony


    【解决方案1】:

    我一直使用 form_widget 来呈现嵌入式表单,但我认为 form_row 也可以正常工作。您应该查看的重要事项是嵌入式表单容器是否具有“数据原型”属性。 然后,您必须将脚本添加到显示表单的页面。在我的例子中,我使用 Mootools,但我猜你可以轻松地将这个脚本转换为 jQuery 或任何其他 javascript 框架:

    这些是我的 js 文件的内容(您应该将“xxx”替换为“data-prototype”属性所在的元素的 id:

    window.addEvent( 'domready', function() {
    var add = function() {
        var collectionHolder = $('XXX');
        var prototype = collectionHolder.getAttribute('data-prototype');
        form = prototype.replace(/\$\$name\$\$/g, collectionHolder.getChildren().length);
        var cont = Elements.from(form);
        collectionHolder.adopt( cont );
    }
    var remove = function() {
        var collectionHolder = $('XXX');
        var child = collectionHolder.getLast();
        child.dispose();
    }
    $$('a.add-link').addEvent('click', function(e){
        e.stop();
        add();
    });
    $$('a.remove-link').addEvent('click', function(e){
        e.stop();
        remove();
    });
    

    });

    这个脚本非常简单,只是添加新元素或删除集合中的最后一个元素。此外,您应该在视图中添加一些 html 以便添加/删除链接:

    <ul class="actions">
    <li>
        <a href="#" class="add-link">
            Add
        </a>
    </li>
    <li>
        <a href="#" class="remove-link">
            Remove last
        </a>
        </li>
    </ul>
    

    我希望它有所帮助,我是 Symfony 的新手,我还在学习,但它对我有用 :)

    【讨论】:

    • 事实上,文本字段名称或 etapes 并没有显示出来。我只有标签,没有别的!我读到我需要添加 javascript 函数来处理添加和删除按钮,但我会在之后做!
    【解决方案2】:

    我会这样做:

    {% for etape in form.etapes %}
      {{ form_widget(etape.name) }}
    {% endfor %}
    

    我可能是错的,因为我不使用树枝模板。但这个想法在 php-templates 中对我有用。

    【讨论】:

      【解决方案3】:

      PHP 模板中..

          `<?php foreach ($form['etapes'] as $etapesField) : ?>
      <?php echo $view['form']->errors($etapesField) ?>
      <?php echo $view['form']->widget($etapesField) ?>
      <?php endforeach; ?>`
      

      【讨论】:

        【解决方案4】:

        好的,有两件事:

        1 - 在树枝模板中显示表单的常规方式:

            {{ form_row(form) }}
        

        模板系统能够级联(对不起,大概的英文),这意味着表单中的所有子字段都将被渲染以及它的封装表单。因此,无需通过调用 form.etapes 直接渲染孩子。

        2 - 我相信你的问题真的在于实例化。如果您以这种方式创建表单:

            $form = $this->createForm(new TryType()));
        

        甚至是这样:

            $model = new Try();
            $model->setEtapes(array());
        
            $form = $this->createForm(new TryType(), $model));
        

        那么您的表单什么也不呈现是正常的,因为它直接显示的 Etape 字段的数量取决于您为模型提供的 Etape 实例的数量。如果您提供一个空数组,则不会呈现 Etape 字段。显示单个字段时应该做的事情是:

            $model = new Try();
            $model->setEtapes(array(new Etape())); // Empty Etape
        
            $form = $this->createForm(new TryType(), $model));
        

        因此,您可以在集合类型中添加任意数量的字段:

            $model = new Try();
            $model->setEtapes(array(
                new Etape('Étape 1'),
                new Etape('Étape 2'),
                ...
            ));
        
            $form = $this->createForm(new TryType(), $model));
        

        【讨论】:

          【解决方案5】:

          由于您使用的是子表单,请执行此操作;

          $builder
              ->add(
                  'etapes',
                  'collection',
                  array(
                      'type'          => new EtapeType(),
                      'allow_add'     => true,
                      'allow_delete'  => true,
                  )
              )
              ->getForm()
          ;
          

          你在twig中的显示方式并不重要。这取决于你想要什么。 form_row、form_widget 都应该可以正常工作。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-06-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多