情景:
我知道我应该添加一个事件订阅者类,如in the documentation
所示$ event有一个setData方法。可能我必须使用它。如何从控制器访问此方法?
其他信息: 我在使用Doctrine。目前我正在创建一个Doctrine实体并将其传递给如下形式:
$product = new Product(); $form = $this->createForm(new ProductType(), $product);
答案 0 :(得分:0)
您不必在$ event对象上使用setData()。您需要实施on POST_SET_DATA
逻辑,根据您的数据构建表单the way you want。
然后,您可以使用网络服务的回复初始化您的表单(在您的控制器内)。
(注意:自版本2.1以来,不推荐使用SET_DATA表单事件。它将在版本2.3中被删除)
<强>更新强>
您可以将数组设置为表单数据,并使用DataTransformer
按照您希望的方式构建表单数据。在上次旧金山Symfony Live期间,请查看Data Transformation part Symfony 2 Form Tricks。
答案 1 :(得分:0)
这是我最终解决的问题。不确定这是否是最佳方式,因此这个答案没有标记为正确,以鼓励其他更多体验Symfony用户提出更好的解决方案。
我不喜欢这个解决方案,我不能再将整个产品实体传递给表单,但必须将每个属性分别添加到options数组中:
无论如何,这就是它现在的实施方式:
动态数据使用options数组作为createForm()的第二个参数传递:
// ExampleController.php
use Acme\ExampleBundle\Entity\Product;
public function addAction()
{
// choices contains the dynamic data I am fetching from the webservice in my actual code
$choices = array("key1" => "value1", "key2" => "value2");
// now create a new Entity
$product = new Product();
// and some attributes already have values for some reason
$product->setPrice(42);
$form = $this->createForm(new AddproductType(),
array(
"choices" => $choices,
"price" => $product->getPrice()
)
);
if ($request->isMethod('POST')) {
$form->bind($request);
if ($form->isValid()) {
// ... standard symfony stuff here
}
}
return array(
'form' => $form->createView()
);
}
现在为表单类。请注意事件侦听器部分和setDefaultOptions方法。
// ProductType.php
namespace Acme\ExampleBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class ProductType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$formFactory = $builder->getFormFactory();
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (\Symfony\Component\Form\FormEvent $event) use ($formFactory) {
// get the option array passed from the controller
$options = $event->getData();
$choices = $options["choices"];
$event->getForm()->add(
// add a new element with radio buttons to the form
$formFactory->createNamed("my_dynamic_field_name", "choice", null, array(
"empty_value" => "Choose an option",
"label" => "My dynamic field: ",
"choices" => $choices
)
)
);
}
);
// ... add other form elements
$builder->add("price", "text");
// ..
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
// register choices as a potential option
$resolver->setDefaults(array(
'choices' => null
));
}
}