我使用entity
表单类型来提供表单中Position
个实体的列表。我经常使用它(每个都有相同的“设置”代码来定制它),我决定从中制作自定义表单类型以便更好地重复使用。
这是当前的表单类型:
class PositionType extends AbstractType
{
private $om;
public function __construct(ObjectManager $om, $mode)
{
$this->om = $om;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
// I need to pass "mode" as an option when building the form.
$mode = ???
$query_builder = function (EntityRepository $em) use ($mode) {
// Limit the positions returned based on the editing mode
return $em
->createQueryBuilder('Position')
->orderBy('Position.name')
->leftJoin('Position.type', 'Type')
->andWhere('Type.id IN (:ids)')
->setParameter('ids', Type::typesForMode($mode))
;
};
$resolver
->setRequired(array('mode'))
->setDefaults(array(
'label' => 'Position',
'class' => 'AcmeBundle:Position',
'property' => 'name',
'query_builder' => $query_builder,
'empty_value' => '',
'empty_data' => null,
'constraints' => array(
new NotBlank(),
),
))
;
}
public function getParent()
{
return 'entity';
}
public function getName()
{
return 'position';
}
}
不要担心查询构建器中的细节,这无关紧要。重要的部分是我正在尝试在查询构建器中使用表单类型选项。
我该怎么做?问题是我无法在$mode
中使用setDefaultOptions
(我希望传递以更改查询构建器的选项)。
我开始寻找一种从buildForm
内部设置查询构建器的方法,但我不确定我能做到这一点。
答案 0 :(得分:1)
这很容易实现。您可以构建一个取决于其他选项的选项。
OptionResolver Component - Default Values that Depend on another Option
基本上你会这样做:
$resolver
->setRequired(array('mode', 'em')) // "em" for EntityManager as well
->setDefaults(array(
'label' => 'Position',
'class' => 'AcmeBundle:Position',
'property' => 'name',
#####################################################
'query_builder' => function(Options $options){
// Obviously you will need to pass the EntityManager
$em = $options['em'];
// Limit the positions returned based on the editing mode
return $em
->createQueryBuilder('Position')
->orderBy('Position.name')
->leftJoin('Position.type', 'Type')
->andWhere('Type.id IN (:ids)')
->setParameter('ids', Type::typesForMode($options['mode'])) //
;
},
####################################
'empty_value' => '',
'empty_data' => null,
'constraints' => array(
new NotBlank(),
),
))
;
这只是OptionsResolver
可以做什么的粗略表示。希望它有所帮助:)
答案 1 :(得分:0)
您可以使用表单选项将变量传递给表单构建器 例如在控制器中;
public function createAction()
{
$form = $this->formFactory->create('client', $client, array('name' => 'create'));
return $this->template->renderResponse('bundle:add.html.twig', array('form' => $form->createView()));
}
并以您的表格类型;
class PositionType extends AbstractType
{
private $mode;
public function buildForm(FormBuilderInterface $builder, array $options)
{
$this->mode = $options['name'];
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
// I need to pass "mode" as an option when building the form.
$mode = ???
$query_builder = function (EntityRepository $em) use ($this->mode) {
// Limit the positions returned based on the editing mode
return $em
->createQueryBuilder('Position')
->orderBy('Position.name')
->leftJoin('Position.type', 'Type')
->andWhere('Type.id IN (:ids)')
->setParameter('ids', Type::typesForMode($mode))
;
};
$resolver
->setRequired(array('mode'))
->setDefaults(array(
'label' => 'Position',
'class' => 'AcmeBundle:Position',
'property' => 'name',
'query_builder' => $query_builder,
'empty_value' => '',
'empty_data' => null,
'constraints' => array(
new NotBlank(),
),
))
;
}
}