Symfony 扩展了一个表单,依赖于提交数据
Symfony extends a form with dependencies from submit data
我正在尝试扩展我的表格,但我不知道该怎么做...
问题
我的父 formType 取决于一个选项。但我想从子表单中提供该选项。在 symfony documentation 中,他们解释了一种添加依赖于提交数据的动态字段的方法。但是如果它有一个带有 DataTransformer 的字段?,因为在 FormInterface 中我无法添加它。
代码
class TransactionApiType extends AbstractApiType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$app = $options['app'];
$builder
->add('gamer', TextType::class)->addModelTransformer(new GamerExternalIdToStringCreateIfNotExistTransformer($em, $app))
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => Transaction::class,
))
->setAllowedTypes('app', ['AppBundle\Entity\App'])
;
}
}
class TransactionMultiAppConfByAppApiType extends TransactionApiType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('app_id',
EntityType::class,
[
'property_path' => 'app',
'required' => true,
'description' => 'App id',
'class' => App::class,
])
;
// I need pass $options['app'] here to work (App will be submitted),
// How can do? or other possibilities
parent::buildForm($builder, $options);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => Transaction::class,
)
;
}
}
提前致谢:-)
在 formEvents 中使用 DataTransformers 添加字段未启用https://github.com/symfony/symfony/issues/9355
但是有一个"hack"
相关这里Symfony2 form events and model transformers(总结它需要创建一个customType ...)
我的解决方案是
class TransactionMultiAppConfByAppApiType extends TransactionApiType
{
// ...
parent::buildForm($builder, $options);
$optionsApp = $builder->get('gamer')->getAttributes()['data_collector/passed_options'];
$builder->remove('gamer');
$builder->get('app_id')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($em, $optionsApp) {
/** @var App $app */
$app = $event->getForm()->getData();
$f = $event->getForm()->getParent();
if ($app)
{
$f
->add('gamer', GamerIdWithExternalIdCustomType::class, $optionsApp + ['em' => $em, 'app' => $app])
;
}
});
// ...
}
class GamerIdWithExternalIdCustomType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addModelTransformer(new GamerExternalIdToStringCreateIfNotExistTransformer($options['em'], $options['app']));
}
public function getParent()
{
return TextType::class;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver
->setRequired([
'em',
'app',
]);
}
}
我正在尝试扩展我的表格,但我不知道该怎么做...
问题
我的父 formType 取决于一个选项。但我想从子表单中提供该选项。在 symfony documentation 中,他们解释了一种添加依赖于提交数据的动态字段的方法。但是如果它有一个带有 DataTransformer 的字段?,因为在 FormInterface 中我无法添加它。
代码
class TransactionApiType extends AbstractApiType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$app = $options['app'];
$builder
->add('gamer', TextType::class)->addModelTransformer(new GamerExternalIdToStringCreateIfNotExistTransformer($em, $app))
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => Transaction::class,
))
->setAllowedTypes('app', ['AppBundle\Entity\App'])
;
}
}
class TransactionMultiAppConfByAppApiType extends TransactionApiType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('app_id',
EntityType::class,
[
'property_path' => 'app',
'required' => true,
'description' => 'App id',
'class' => App::class,
])
;
// I need pass $options['app'] here to work (App will be submitted),
// How can do? or other possibilities
parent::buildForm($builder, $options);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => Transaction::class,
)
;
}
}
提前致谢:-)
在 formEvents 中使用 DataTransformers 添加字段未启用https://github.com/symfony/symfony/issues/9355
但是有一个"hack" 相关这里Symfony2 form events and model transformers(总结它需要创建一个customType ...)
我的解决方案是
class TransactionMultiAppConfByAppApiType extends TransactionApiType
{
// ...
parent::buildForm($builder, $options);
$optionsApp = $builder->get('gamer')->getAttributes()['data_collector/passed_options'];
$builder->remove('gamer');
$builder->get('app_id')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($em, $optionsApp) {
/** @var App $app */
$app = $event->getForm()->getData();
$f = $event->getForm()->getParent();
if ($app)
{
$f
->add('gamer', GamerIdWithExternalIdCustomType::class, $optionsApp + ['em' => $em, 'app' => $app])
;
}
});
// ...
}
class GamerIdWithExternalIdCustomType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addModelTransformer(new GamerExternalIdToStringCreateIfNotExistTransformer($options['em'], $options['app']));
}
public function getParent()
{
return TextType::class;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver
->setRequired([
'em',
'app',
]);
}
}