在Symfony项目中,我有一个注册表格,其中,在其他字段中,我必须显示所选用户。用户取自用户实体。
我需要保存用户ID(在"注册实体"中保存用户ID(,但在表单字段中显示用户全名。如果没有选择字段?
我该如何管理我的结论是用
创建自定义字段- 非形式标签(跨度(中的名称
- 隐藏输入中的ID
但是在这种情况下,我不知道如何实现。
我的用户实体:
class User extends BaseUser
{
...
public function __toString()
{
return ($this->lastName . " " . $this->firstName. " [".$this->getId()."]");
}
}
我的注册实体:
class Registration
{
/**
* @var MyBundleEntityUser
*
* @ORMManyToOne(targetEntity="MyBundleEntityUser")
* @ORMJoinColumns({
* @ORMJoinColumn(name="userId", referencedColumnName="id")
* })
*/
private $user;
...
}
我的第一个明显尝试是将用户字段作为注册表格。
class RegistrationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('user', EntityType::class, [
'label' => 'user.name',
'attr' => [
'class' => 'reguser',
],
'class' => 'MyBundleEntityUser',
]);
}
}
我有一个选择,其中显示了用户名,并且ID为值。这是符合人体工程学的最大问题:我可能有数千名用户。我无法显示这么大的列表。
所以我考虑了一个自动完成字段。
$builder
->add('user', TextType::class, [
'label' => 'user.name',
'attr' => [
'class' => 'reguser userpicker',
],
]);
这里的问题是多个:在自动完成字段中,我显然显示名称(最终用户搜索名称,而不是ID(,但是当我保存时,这将是毫无用处的,因为我需要用户ID。
因此,我开始使用自动完成的JS玩具,以在额外的跨度中显示名称,并用ID替换自动完成的值。这是hacky且不可用的,因为当我编辑时,我的__tostring((值来自文本字段中显示的用户。
实现此目的的一种方法是在您的领域添加DataTransformer
。
整个文档可在此处提供。
1。创建您的DataTransformer
此类将将您的用户名(即字符串(转换为User
。
namespace AppBundleFormDataTransformer;
// your User class :
use AppBundleEntityUser;
use DoctrineORMEntityManagerInterface;
use SymfonyComponentFormDataTransformerInterface;
use SymfonyComponentFormExceptionTransformationFailedException;
class implements DataTransformerInterface
{
private $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}
/**
* Transforms an object (user) to a string (number).
*
* @param User|null $user
* @return string
*/
public function transform($user)
{
if (null === $user) {
return '';
}
return (string) $user;
}
/**
* Transforms a string (username) to an object (user).
*
* @param string $username
* @return User|null
* @throws TransformationFailedException if object (user) is not found.
*/
public function reverseTransform($username)
{
// no username ? It's optional, so that's ok
if (!$issueNumber) {
return;
}
$user = $this->em
->getRepository('AppBundle:User')
// query for the issue with this id
->findByUsername($username)
;
if (null === $user) {
// causes a validation error
// this message is not shown to the user
// see the invalid_message option
throw new TransformationFailedException(sprintf(
'User with username %s not found',
$username
));
}
return $user;
}
}
2。将您的数据转换器附加到您的类型
您将必须将EntityManager作为参数,使用服务或声明用USERNAMETOUSERTRASSFORMER作为具有正确参数的服务
$builder
->add('user', EntityType::class, [
'label' => 'user.name',
'attr' => [
'class' => 'reguser',
],
'class' => 'MyBundleEntityUser',
]);
$builder
->get('user')
->addModelTransformer(new UsernameToUserTransformer($this->em))
;