Symfony2集合总是空的

时间:2015-10-26 23:07:28

标签: forms symfony collections

我有一个我无法解决的问题。我有2个实体:

<?php
namespace ...\Entity;

// ...

/**
 * Pregunta
 *
 * @ORM\Table(name="pregunta", indexes={@ORM\Index(name="fk_respuesta_tipo_respuesta1_idx", columns={"tipo_respuesta_id"}))})
 * @ORM\Entity 
 */
class Pregunta {

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var \Doctrine\Common\Collections\Collection
     *
     * @ORM\ManyToMany(targetEntity="...\Entity\Respuesta", mappedBy="pregunta")
     */
    private $respuesta;


    public function __construct() {
        $this->tipoPrueba = new \Doctrine\Common\Collections\ArrayCollection();
        $this->respuesta = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Add respuesta
     *
     * @param ...\Entity\Respuesta $respuesta
     * @return Pregunta
     */
    public function addRespuesta(...\Entity\Respuesta $respuesta) {
        $this->respuesta[] = $respuesta;

        return $this;
    }

    /**
     * Remove respuesta
     *
     * @param ...\Entity\Respuesta $respuesta
     */
    public function removeRespuesta(...\Entity\Respuesta $respuesta) {
        $this->respuesta->removeElement($respuesta);
    }

    /**
     * Get respuesta
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getRespuesta() {
        return $this->respuesta;
    }

    function setRespuesta(\Doctrine\Common\Collections\Collection $respuesta) {
        $this->respuesta = $respuesta;
    }
}

然后我有Respuesta实体:

<?php
class Respuesta {

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="texto_respuesta", type="text", nullable=false)
     */
    private $textoRespuesta;

    // ...

我有一个PreguntaType,其字段和RespuestaType

的集合
/**
 * @param FormBuilderInterface $builder
 * @param array $options
 */
public function buildForm(FormBuilderInterface $builder, array $options) {
    $builder
            ->add('titulo', 'textarea', array("label" => "Enunciado: ", "required" => true, "attr" => array('class' => 'form-control')))
            ->add('numeroPagina', 'integer', array("label" => "Página: ", "required" => true, "attr" => array('class' => 'form-control')))
            ->add('areaConocimiento', 'entity', array('class' => 'UciBaseDatosBundle:AreaConocimiento', 'required' => false, 'attr' => array('style' => 'width: 100%')))
            ->add('trianguloTalento', 'entity', array('class' => 'UciBaseDatosBundle:TrianguloTalento', 'required' => false, 'attr' => array('style' => 'width: 100%')))
            ->add('capitulo', 'entity', array('class' => 'UciBaseDatosBundle:Capitulo', 'required' => false, 'attr' => array('style' => 'width: 100%')))
            ->add('grupoProcesos', 'entity', array('class' => 'UciBaseDatosBundle:GrupoProcesos', 'required' => false, 'attr' => array('style' => 'width: 100%')))
            ->add('tipoPrueba', 'entity', array('class' => 'UciBaseDatosBundle:TipoPrueba', 'expanded' => true, 'multiple' => true, 'required' => false, 'attr' => array('style' => 'width: 100%')))
            ->add('libro', 'entity', array('class' => 'UciBaseDatosBundle:Libro', 'required' => false, 'attr' => array('style' => 'width: 100%')))
            ->add('respuesta', 'collection', array(
                'type' => new RespuestaType(),
                'prototype' => true,
                'allow_add' => true,
                'by_reference' => false,
                'allow_delete' => true,
                'label' => ' '
    ));
}

/**
 * @param OptionsResolverInterface $resolver
 */
public function setDefaultOptions(OptionsResolverInterface $resolver) {
    $resolver->setDefaults(array(
        'data_class' => 'Uci\Bundle\BaseDatosBundle\Entity\Pregunta'
    ));
}

但是,当我调试表单提交时,如果我将我的集合设置为'required' => true,则会抛出此错误An invalid form control with name='...[respuesta][Respuesta0][RespuestaField]' is not focusable。另一方面,如果我将其设置为'required' => false,我的收藏品将会被设置为<form action="{{ path('uci_administrador_registrarPregunta', { 'idTipoRespuesta': tipoRespuesta.id }) }}" name="formulario" method="POST" enctype="multipart/form-data"> <h3 class="thin text-center">Registrar una nueva pregunta {{ tipoRespuesta.nombre }}</h3> <p class="text-center text-muted">{{ tipoRespuesta.explicacion }}</p> <hr> {% if error %} <div style="color:red">{{ error }}</div> {% endif %} <div class="row top-margin"> <div class="cols-xs-12 col-sm-10 col-md-8 col-lg-8"> {{ form_row(form.titulo) }} </div> </div> <div class="row top-margin"> <div class="cols-xs-12 col-sm-10 col-md-8 col-lg-8"> {{ form_row(form.numeroPagina) }} </div> </div> <div class="row top-margin"> <div class="cols-xs-12 col-sm-10 col-md-8 col-lg-8"> {{ form_row(form.areaConocimiento) }} </div> </div> <div class="row top-margin"> <div class="cols-xs-12 col-sm-10 col-md-8 col-lg-8"> {{ form_row(form.capitulo) }} </div> </div> <div class="row top-margin"> <div class="cols-xs-12 col-sm-10 col-md-8 col-lg-8"> {{ form_row(form.grupoProcesos) }} </div> </div> <div class="row top-margin"> <div class="cols-xs-12 col-sm-10 col-md-8 col-lg-8"> {{ form_row(form.trianguloTalento) }} </div> </div> <div class="row top-margin"> <div class="cols-xs-12 col-sm-10 col-md-8 col-lg-8"> {{ form_row(form.tipoPrueba) }} </div> </div> <div class="row top-margin"> <div class="cols-xs-12 col-sm-10 col-md-8 col-lg-8"> {{ form_row(form.libro) }} </div> </div> <br> <hr> <h3>Respuestas</h3><br> <div class="respuestas" data-prototype="{{ form_widget(form.respuesta.vars.prototype)|e }}"> {# iterate over each existing tag and render its only field: name #} {% for respuesta in form.respuesta %} <div class="row top-margin"> <div class="cols-xs-12 col-sm-10 col-md-8 col-lg-8"> {{ form_row(respuesta.correcta) }} </div> </div> {% endfor %} </div> <br><br> <div class="row"> <div class="col-lg-8"> </div> <div class="col-lg-4 text-right"> <button class="btn btn-action" type="submit">Registrar</button> </div> </div> {{ form_rest(form) }} </form> 。字段总是空的。

这是我的TWIG文件:

var $collectionHolder;
// setup an "add a tag" link
var $addTagLink = $('<a href="#" class="add_tag_link">Añadir respuesta</a>');
var $newLinkLi = $('<div></div>').append($addTagLink);
function addTagForm($collectionHolder, $newLinkLi) {
    // Get the data-prototype explained earlier
    var prototype = $collectionHolder.data('prototype');
    // get the new index
    var index = $collectionHolder.data('index');
    // Replace '__name__' in the prototype's HTML to
    // instead be a number based on how many items we have
    var newForm = prototype.replace(/__name__/g, 'Respuesta' + index);
    // increase the index with one for the next item
    $collectionHolder.data('index', $collectionHolder.find(':input').length);
    // Display the form in the page in an li, before the "Add a tag" link li
    var $newFormLi = $('<div style="background-color:#F6F6F6; border-radius:10px;padding: 25px;border: 5px solid #003c70;margin: 5px;"></div><br>').append(newForm);
    $newLinkLi.before($newFormLi);
}
document.ready = function () {
    // Get the ul that holds the collection of tags
    $collectionHolder = $('div.respuestas');
    // add the "add a tag" anchor and li to the tags ul
    $collectionHolder.append($newLinkLi);
    // count the current form inputs we have (e.g. 2), use that as the new
    // index when inserting a new item (e.g. 2)
    $collectionHolder.data('index', $collectionHolder.find(':input').length);
    $addTagLink.on('click', function (e) {
        // prevent the link from creating a "#" on the URL
        e.preventDefault();
        // add a new tag form (see next code block)
        addTagForm($collectionHolder, $newLinkLi);
    });

    // ...
}

我使用一些javascript来添加我的收藏表格:

@ComponentScan("path to respective Component") 

我真的很感激任何帮助。

感谢。

2 个答案:

答案 0 :(得分:1)

我的问题出在我的javascript中。我不知道为什么我以前的代码不起作用,但我改变了它的工作原理。我的javascript如下:

var collectionHolder = $('#respuestas');
var prototype = collectionHolder.attr('data-prototype');
var form = prototype.replace(/__name__/g, collectionHolder.children().length); //importante
var removeFormA = $('<a href="#" onclick="addTagFormDeleteLink(event, this);">Borrar</a>');
var newLi = $('<li></li>');
newLi.append(form);
newLi.append(removeFormA);
collectionHolder.append(newLi);

这是我的TWIG文件的一部分:

<ul id="respuestas" data-prototype="{{ form_widget(form.respuesta.vars.prototype)|e }}">
{% for respuesta in form.respuesta %}
      <li> {{ form_row(respuesta) }}</li>
{% endfor %}
</ul>

我希望它可以帮助别人。

问候。

答案 1 :(得分:0)

您是否试图隐藏表单中的某些字段?看起来某些字段是必需的,但实际上并未在页面中显示,这会阻止浏览器验证表单。请参阅答案:https://stackoverflow.com/a/28340579/4114297

我想知道你为什么只在循环中渲染respuesta.correcta。您可能想要呈现while respuesta项:

<div class="respuestas" data-prototype="{{ form_widget(form.respuesta.vars.prototype)|e }}">
    {# iterate over each existing tag and render its only field: name #}
    {% for respuesta in form.respuesta %}
        <div class="row top-margin">
            <div class="cols-xs-12 col-sm-10 col-md-8 col-lg-8">
                {{ form_row(respuesta) }} {# <- Here #}
            </div>
        </div>
    {% endfor %}
</div>

如果您需要隐藏和/或预填充某些字段,则可以执行此操作RespuestaType