symfony 符号2(>= 2.3):如何从子窗体监听父窗体事件?

30byixjq  于 2022-12-13  发布在  其他
关注(0)|答案(1)|浏览(108)

我有一个自定义的FormType,当父窗体持续存在时,它需要将自身添加到父实体中。
在Symfony〈2.3中,这可以通过执行以下操作来完成:

class FooType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        parent::buildForm($builder, $options);
        ...
        $builder->getParent()->addEventSubscriber(new FooSubscriber)
    }
}

class FooSubscriber implements EventSubscriberInterface
{
    static function getSubscribedEvents()
    {
        return array(
            FormEvents::POST_SUBMIT => 'postSubmit'
        );
    }
}

但是升级到Symfony 2.6之后,我发现$builder->getParent()被删除了。但是现在我不能听父文件提交。
因此,我将侦听器添加到我的构建器中,并从订阅服务器中引用父表单。但这实际上并不起作用,因为我检查父表单是否有效-但它不是有效的,因为它还没有提交:

function postSubmit(FormEvent $e)
{
    if ($e->getForm()->getParent()->getRoot()->isValid()) {
        //this gives 'false'

这个false是由下一段代码引起的:

// Symfony\Component\Form\Form.php @ line 744
public function isValid()
{
    if (!$this->submitted) {
        return false;
    }

而且因为父表单首先循环遍历所有查尔兹表单并提交,然后才对自身设置$this->submitted = true......我不确定父表单是否有效。

TL;DR

如何在不调整父窗体的情况下将Eventlistener添加到父窗体?我希望FooType可以添加到所有窗体,而不必知道/记住为该FooType特定的逻辑。

mrfwxfqh

mrfwxfqh1#

我需要相同的功能,因为我有一个自定义表单字段,在更新所有Map字段后,它需要父实体。不幸的是,在父表单上运行SUBMIT之前,调用了子表单的POST_SUBMIT。
最后我将eventDispatcher传递给子进程,并将侦听器绑定到那里。我需要两个侦听器来完成这项工作:通过引用将$generatedPassword传递给闭包允许您将子事件中的数据共享给父事件。

父代::生成窗体

$builder->add('generate_password', GeneratePasswordType::class, [
    'event_dispatcher' => $builder->getEventDispatcher(),
]);

子系::建置表单

// first listen to submit event to get current field value
$generateNewPassword = false;
$builder->addEventListener(FormEvents::SUBMIT, function (FormEvent $event) use (&generateNewPassword) {
    $generateNewPassword = null !== $event->getData();
});

// then run updater after parent entity has been updated
$parentDispatcher = $options['event_dispatcher'];
$parentDispatcher->addListener(FormEvents::POST_SUBMIT, function (FormEvent $event) use (&$generateNewPassword) {
    $user = $event->getData();
    if(true === $generateNewPassword){
        // update password & email user new credentials
    }
}

(The自定义字段是一个复选框,标记为“保存时生成新密码”,用于用户管理模块。它通过电子邮件向用户发送生成的密码,这就是为什么我需要主实体的最新电子邮件地址)

相关问题