我希望用自定义查询的值填充symfony2中的选择框。我已经尽可能地简化了。
控制器class PageController extends Controller
{
public function indexAction()
{
$fields = $this->get('fields');
$countries = $fields->getCountries(); // returns a array of countries e.g. array('UK', 'France', 'etc')
$routeSetup = new RouteSetup(); // this is the entity
$routeSetup->setCountries($countries); // sets the array of countries
$chooseRouteForm = $this->createForm(new ChooseRouteForm(), $routeSetup);
return $this->render('ExampleBundle:Page:index.html.twig', array(
'form' => $chooseRouteForm->createView()
));
}
}
ChooseRouteForm
class ChooseRouteForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
// errors... ideally I want this to fetch the items from the $routeSetup object
$builder->add('countries', 'choice', array(
'choices' => $this->routeSetup->getCountries()
));
}
public function getName()
{
return 'choose_route';
}
}
您可以使用..将选择传递给表单
$chooseRouteForm = $this->createForm(new ChooseRouteForm($routeSetup), $routeSetup);
那么在你的表单中…
private $countries;
public function __construct(RouteSetup $routeSetup)
{
$this->countries = $routeSetup->getCountries();
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('countries', 'choice', array(
'choices' => $this->countries,
));
}
更新(和改进)2.8 +
首先,你真的不需要传入国家作为路由对象的一部分,除非它们将被存储在DB中。
如果在DB中存储可用的国家,则可以使用事件侦听器。如果没有(或者不想使用侦听器),可以在选项区域中添加国家。
利用期权
In the controller.
$chooseRouteForm = $this->createForm(
ChooseRouteForm::class,
// Or the full class name if using < php 5.5
$routeSetup,
array('countries' => $fields->getCountries())
);
在你的形式…
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('countries', 'choice', array(
'choices' => $options['countries'],
));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver
->setDefault('countries', null)
->setRequired('countries')
->setAllowedTypes('countries', array('array'))
;
}
使用侦听器(如果模型中有国家数组)
In the controller.
$chooseRouteForm = $this->createForm(
ChooseRouteForm::class,
// Or the full class name if using < php 5.5
$routeSetup
);
在你的形式…
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->addEventListener(FormEvents::PRE_SET_DATA, function(FormEvent $event) {
$form = $event->getForm();
/** @var RouteSetup $routeSetup */
$routeSetup = $event->getData();
if (null === $routeSetup) {
throw new 'Exception('RouteSetup must be injected into form');
}
$form
->add('countries', 'choice', array(
'choices' => $routeSetup->getCountries(),
))
;
})
;
}
我还不能评论或投票,所以我只能在这里回复Qoop的回答:除非您开始使用表单类型类作为服务,否则您的建议将有效。一般应该避免通过构造函数向表单类型对象添加数据。
把表单类型类想象成类——它是对表单的一种描述。当你创建一个实例的形式(通过构建它),你得到的对象的形式,是建立在表单类型的描述,然后填入数据。看看这个:http://www.youtube.com/watch?v=JAX13g5orwo -这种情况在演示文稿的31分钟左右被描述。
你应该使用表单事件FormEvents::PRE_SET_DATA并在表单被注入数据时操作字段。见:http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html customizing-your-form-based-on-the-underlying-data
我得到它的工作通过调用getData上的生成器
FormBuilderInterface $builder
//控制器$myCountries = $this->myRepository->all(['continent' => 'Africa']);
$form = $this->createForm(CountriesType::class, $myCountries);
//FormType use Symfony'Component'Form'Extension'Core'Type'ChoiceType;
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('pages', ChoiceType::class, [
'choices' => $builder->getData()
])
;
}