首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >Symfony2和Selectize.js:在实体字段类型中持久化新项的最清晰的方法?

Symfony2和Selectize.js:在实体字段类型中持久化新项的最清晰的方法?
EN

Stack Overflow用户
提问于 2015-04-23 16:17:45
回答 3查看 1.4K关注 0票数 12

BandType,中,我有一个添加实体Tag的Symfony2

代码语言:javascript
代码运行次数:0
运行
复制
->add('tags', 'entity', [
     'label' => 'Tags',
     'class' => 'DbBundle:Tag',
     'property' => 'title',
     'multiple'  =>  true,
])

这将生成多个select元素,其中我可以从数据库(Doctrine)中选择现有标记。但是,我需要添加动态的新标记,这些标记还不存在。

在客户端,我使用jQuery插件Selectize.js,它允许我添加新的标记来选择框。但是在提交表单之后,新的标记不会保存

因此,我的问题是-从复选框(实体字段类型)中持久化新项的最清晰的方法是什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-04-24 09:45:24

对实体使用数据变压器。在reverseTransform方法中,如果找不到新添加的带,只需在那里创建它,而不是抛出一个TransformationFailedException。

票数 11
EN

Stack Overflow用户

发布于 2016-01-29 14:14:44

一个可能的解决方案是使用FormEvents。下面是示例代码:

代码语言:javascript
代码运行次数:0
运行
复制
namespace AppBundle\Form;

use AppBundle\Entity\Tag;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\OptionsResolver\OptionsResolver;

class PostType extends AbstractType
{
    /**
     * @var ObjectManager
     */
    private $manager;

    /**
     * Constructor
     *
     * @param ObjectManager $manager
     */
    public function __construct(ObjectManager $manager)
    {
        $this->manager = $manager;
    }

    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('title')
            ->add('content')
            ->add('tags')
        ;
        $builder->get('tags')->addEventListener(
            FormEvents::PRE_SUBMIT,
            function (FormEvent $event) {
                $choiceList = $event->getForm()->getConfig()->getAttribute('choice_list');
                $array = is_null($event->getData()) ? [] : $event->getData();
                $choices = $choiceList->getChoicesForValues($array);

                if (count($choices) !== count($array)) {
                    $values = $choiceList->getValuesForChoices($choices);
                    $diff = array_merge(array_diff($values, $array), array_diff($array, $values));

                    foreach ($diff as $value) {
                        $new = new Tag($value);
                        $this->manager->persist($new);
                        $this->manager->flush();
                        $values[] = $new->getId();
                    }

                    $event->setData($values);
                }
            }
        );
    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\Post'
        ));
    }
}
票数 0
EN

Stack Overflow用户

发布于 2016-01-29 01:50:20

正如在另一个答案中所描述的,您将希望为您的实体使用一个数据变压器,如果您找不到用户所要求的实体,则返回一个新实体。

有很多种方法可以解决这个问题。这是一种方法,从刚刚使用selectize.js的应用程序中得到简化,但是这些概念适用于您的前端的anyUI。

代码语言:javascript
代码运行次数:0
运行
复制
class SubjectTransformer implements DataTransformerInterface
{
    protected $em;

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

    //public function transform($val) { ... }

    public function reverseTransform($str)
    {
        $repo = $this->em->getRepository('AppBundle:Subject');

        $subject = $repo->findOneByName($str);
        if($subject)
            return $subject;

        //Didn't find it, so it must be new 
        $subject = new Subject;
        $subject->setName($str);
        $this->em->persist($subject);

        return $subject;
    }
}

具体来说,这个用于DataTransformer字段的entry_typeCollectionType

  • 在其构造函数中接受实体管理器。
  • reverseTransform中,使用EM从数据库中检索值
  • 如果找不到一个,则创建一个新实体,并将其持久化。
  • 显式不刷新实体,以防窗体处理器/控制器希望在实际提交新实体之前对其执行额外的验证。

其他可能的变体包括不调用em->persist;调用em->flush;或者(可能在理想情况下)传递服务来管理搜索/创建,而不是直接使用实体管理器。(这样的服务可能实现几乎重复的检测、糟糕的语言过滤,只允许某些用户创建新的标记,等等)

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29829105

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档