我有一个实体:
class UserSettings
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*
* @ORM\OneToOne(targetEntity="User")
* @ORM\JoinColumn(name="id", referencedColumnName="id")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="background_color", type="string", length=10)
*/
private $background_color;
/**
* @var string
*
* @ORM\Column(name="text_color", type="string", length=10)
*/
private $text_color;
.....
我在该实体的存储库中有一个方法,如果该用户的记录存在则返回用户的设置,否则返回默认值。这是方法:
public function getUserSettings( $user_id )
{
$user_preferences = $this->findOneBy(array('id' => $user_id));
if($user_preferences){
return array(
'user_preferences' => array(
'background_color' => $user_preferences->getBackgroundColor(),
'text_color' => $user_preferences->getTextColor()
)
);
}else{
return array(
'user_preferences' => array(
'background_color' => '#000000',
'text_color' => '#FFFFFF'
)
);
}
}
我有一个userSettingsType:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('background_color', TextType::class)
->add('text_color', TextType::class)
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\UserSettings',
));
}
和控制器:
public function usersettingsAction(Request $request)
{
$user = $this->get('security.token_storage')->getToken()->getUser();
$data = $request->request->all();
$user_settings = new UserSettings();
$form = $this->createForm(UserSettingsType::class, $user_settings);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($user_settings);
$em->flush();
}
return $this->render('user/user_settings.html.twig', $user_settings );
}
问题是:如何在第一次加载时使用存储库方法getUserSettings()来水合表单字段?
我找到的帖子/答案/教程/烹饪书都没有帮我解决这个问题。
答案 0 :(得分:1)
您可以将UserSettingsType定义为服务以注入服务容器以访问doctrine存储库,然后在表单类型中使用PRE_SET_DATA
表单事件(请查看doc有关formEvents的信息):
1-将您的表单类型声明为服务注入服务容器
form.type.user_setting:
class: YourProject\YourBundle\Form\Type\UserSettingsType
arguments:
- '@service_container'
tags:
- { name: form.type, alias: user_setting_type }
2-然后在你的控制器中调用它:
$form = $this->createForm($this->get('form.type.user_setting'), $user_settings);
3-最后在您的UserSettingsType中使用容器访问doctrine和PRE_SET_DATA事件,以便在第一次加载时对表单字段进行水合处理" :
<?php
class UserSettingsType extends AbstractType
{
protected $container;
public function __construct($container)
{
$this->container = $container;
}
//an example to access to your repository
public funtion myFunction($userId)
{
return $this->container
->get('doctrine')
->getRepository('yourRepository')
->getUserSettings($userId);
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->addEventListener(
FormEvents::PRE_SET_DATA,
function(FormEvent $event) {
$form = $event->getForm();
//get userSettingId if you need it
$userSetting = $event->getData();
$userSettingId = $userSetting->getId();
//you can call 'myFunction' here for example to do want you want
$form
->add('background_color', TextType::class)
->add('text_color', TextType::class)
;
});
}
}
答案 1 :(得分:0)
非常感谢DOZ。
你的意思是写这个:
$user = $this->get('security.token_storage')->getToken()->getUser();
$em = $this->getDoctrine()->getManager();
$user_settings_temp = $em->getRepository('AppBundle:UserSettings')->getUserSettings($user->getId());
$user_settings = new UserSettings();
$user_settings->setUser( $user->getId() );
$user_settings->setBackgroundColor( $user_settings_temp['background_color'] );
$user_settings->setTextColor( $user_settings_temp['text_color'] );
$user_settings->setFontSize( $user_settings_temp['font_size'] );
$user_settings->setMenuEmbedded( $user_settings_temp['menu_embedded'] );
$user_settings->setMenuSide( $user_settings_temp['menu_side'] );
$user_settings->setShowImages( $user_settings_temp['show_images'] );
// Create the form object
$form = $this->createForm(UserSettingsType::class, $user_settings);
在控制器中。
我同意更少&#34;优雅&#34;但我维护的事情更清楚。