首页 > 解决方案 > 使用监听器以表单形式注入的 Symfony 更改对象

问题描述

我正在使用 Symfony 3.4,我有一件奇怪的事情要做,我会尽量解释清楚。

我有一个实体Website和一个WebsiteFormType,在这个WebsiteFormType我有一个像这样的监听器:(buildForm()在formType的第一行)

$builder->addEventSubscriber(new WebsiteListener();

在此侦听器中,我需要检查提交表单时何时更新特定值,如果更新此值,我需要复制我的对象,例如当我更新我的网站并将urlfrom更改http://xxx.xxhttp://yyyy.yy我复制我的第一个网站创建第二个而不是仅仅更新字段url

在此侦听器中,我使用preSubmitand postSubmit

我的问题是,当我更改网址时,我需要更改链接到表单的对象网站。

如果http://xxx.xx是 WebsiteA 并且http://yyyy.yy是 WebsiteB,当我提交 WebsiteA 并更改 url 时,我需要将链接到表单的 WebsiteA 对象从 WebsiteA 更改为 WebsiteB....

这是因为如果我在那之后重新验证表单,它是经过验证的 WebsiteB 而不是 WebsiteA。

不知道你是否理解我的问题:) 谢谢!

标签: symfony

解决方案


尝试使用Doctrine EventSubscriber,例如:

class OrderListener implements EventSubscriber {

protected $statusChanges = false;

public function getSubscribedEvents()
{
    return array(
        'preUpdate',
        'postUpdate',
    );
}

public function preUpdate(PreUpdateEventArgs $args)
{
    $changeSet = $args->getEntityChangeSet();
    foreach ($changeSet as $key => $arr) {

        if ($key === 'status' && (int)$arr[0] !== (int)$arr[1]) {
            $this->statusChanges = true;
        }
    }
}

public function postUpdate(LifecycleEventArgs $args)
{
    $entity = $args->getObject();

    if ($entity instanceof Order && $this->statusChanges) {
        $repo = $args->getObjectManager()->getRepository(Action::class);
        $action = new Action();
        $action->setOrder($entity)
            ->setStatus($entity->getStatus())
            ->setCost($entity->getCost())
            ->setTimeAt(new \DateTime())
            ->setPoint($entity->getPoint())
            ->setDescription($entity->getDescription())
            ->setService($entity->getService())
        ;

        $repo->persistAndFlush($action); // custom method, you can use $args->getObjectManager()->persist($action) and $args->getObjectManager()->flush($action)
    }
}
}

推荐阅读