微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

symfony – 扩展EntityType以允许使用AJAX调用设置额外的选项

我尝试创建一个扩展核心“实体”类型的Symfony Custom类型.

但我想在Select2版本4.0.0中使用它(ajax现在可以使用“select”html元素,而不像以前那样使用隐藏的“输入”).

>此类型应通过扩展“实体”类型创建空选择而不是完整实体列表.

这可以通过设置选项(请参阅configureOption)来实现:

'choices'=>array()

>通过编辑附加到表单的对象,它应该使用对象的当前数据填充select.我解决了这个问题,但只是为了使用以下buildView方法的视图…

Select2识别html“select”的内容,并使用ajax工作.
但是当表单被回发时,Symfony无法识别所选择的选项,(因为没有被允许?)

Symfony\Component\Form\Exception\TransformationFailedException

    Unable to reverse value for property path "user": The choice "28" does not exist or is not unique

我尝试了几种使用EventListeners或Subscribers的方法,但我找不到工作配置.

使用Select2 3.5.*我解决了表单事件的问题并覆盖了隐藏的formtype,但是这里扩展实体类型要困难得多.

如何构建我的类型以让它管理我的entites的逆向转换?

自定义类型:

<?PHP
namespace AppBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

use Symfony\Component\Form\ChoiceList\View\ChoiceView;

class AjaxEntityType extends AbstractType
{
    protected $router;

    public function __construct($router)
    {
        $this->router = $router;
    }

   /**
    * {@inheritdoc}
    */
    public function buildForm(FormBuilderInterface $builder,array $options)
    {   
        $builder->setAttribute('attr',array_merge($options['attr'],array('class'=>'select2','data-ajax--url'=>$this->router->generate($options['route']))));
    }

    /**
    * {@inheritdoc}
    */
    public function buildView(FormView $view,FormInterface $form,array $options)
    {
        $view->vars['attr'] = $form->getConfig()->getAttribute('attr');
        $choices = array();
        $data=$form->getData();
        if($data instanceOf \Doctrine\ORM\PersistentCollection){$data = $data->toArray();}
        $values='';
        if($data != null){
            if(is_array($data)){
                foreach($data as $entity){
                    $choices[] = new ChoiceView($entity->getAjaxName(),$entity->getId(),$entity,array('selected'=>true));
                }
            }
            else{
                $choices[] = new ChoiceView($data->getAjaxName(),$data->getId(),$data,array('selected'=>true));
            }
        }

        $view->vars['choices']=$choices;
    }

   /**
    * {@inheritdoc}
    */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setrequired(array('route'));
        $resolver->setDefaults(array('choices'=>array(),'choices_as_value'=>true));
    }

    public function getParent() {
        return 'entity';
    }

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

父表格

<?PHP
namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class AlarmsType extends AbstractType
{
   /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder,array $options)
    {
        $builder
            ->add('name','text',array('required'=>false))
            ->add('user','ajax_entity',array("class"=>"AppBundle:Users","route"=>"ajax_users"))
            ->add('submit','submit');
    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array('data_class' => 'AppBundle\Entity\Alarms','validation_groups'=>array('Default','form_user')));
    }

    /**
     * @return string
     */
    public function getName()
    {
        return 'alarms';
    }
}
问题解决了.

解决方案是在PRE_SET_DATA和PRE_SUBMIT FormEvents中使用’choices’=> $selectedChoices重新创建表单字段.

可以使用$event-> getData()从事件中重新选择所选内容

看看我创建的包,它实现了这个方法

Alsatian/FormBundle – ExtensibleSubscriber

原文地址:https://www.jb51.cc/ajax/160211.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐