如何在不使用 select 的情况下以 SF 形式显示用户全名和保存用户 ID
How to display user fullname and save user id in SF form, without using select
在一个 symfony 项目中,我有一个注册表单,在其他字段中我必须显示 selected 用户。用户取自用户实体。
我需要保存用户 ID(在注册实体中我保存了 UserId),但在表单字段中显示用户全名。
如果没有 select 字段,我该如何管理?
我的结论是创建一个自定义字段
- 非表单标签中的名称(跨度)
- 隐藏输入中的 id
但在这种情况下我不知道如何实现它。
我的用户实体:
class User extends BaseUser
{
...
public function __toString()
{
return ($this->lastName . " " . $this->firstName. " [".$this->getId()."]");
}
}
我的注册实体:
class Registration
{
/**
* @var \MyBundle\Entity\User
*
* @ORM\ManyToOne(targetEntity="MyBundle\Entity\User")
* @ORM\JoinColumns({
* @ORM\JoinColumn(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' => 'MyBundle\Entity\User',
]);
}
}
我有一个 select 显示用户名和 id 作为值。最大的问题是人体工程学:我可能有几千个用户。我无法显示那么大的列表。
所以我想到了一个自动完成字段。
$builder
->add('user', TextType::class, [
'label' => 'user.name',
'attr' => [
'class' => 'reguser userpicker',
],
]);
这里的问题是多方面的:
在自动完成字段中,我显然显示了名称(最终用户搜索的是名称,而不是 ID)但是当我保存时这将毫无用处,因为我需要用户 ID。
所以我开始玩弄自动完成 js 以在额外的范围内显示名称,并用 id 替换自动完成的值。这是 hacky 并且不可用,因为当我编辑时,我在文本字段中显示了来自用户的 __toString() 值。
实现此目的的一种方法是在您的字段中添加 DataTransformer
。
完整文档可用here。
1.创建您的 DataTransformer
此 class 会将您的用户名(字符串)转换为 User
。
namespace AppBundle\Form\DataTransformer;
// your User class :
use AppBundle\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;
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 作为参数,或者使用正确的参数将 UsernameToUserTransformer 声明为服务
$builder
->add('user', EntityType::class, [
'label' => 'user.name',
'attr' => [
'class' => 'reguser',
],
'class' => 'MyBundle\Entity\User',
]);
$builder
->get('user')
->addModelTransformer(new UsernameToUserTransformer($this->em))
;
在一个 symfony 项目中,我有一个注册表单,在其他字段中我必须显示 selected 用户。用户取自用户实体。
我需要保存用户 ID(在注册实体中我保存了 UserId),但在表单字段中显示用户全名。 如果没有 select 字段,我该如何管理?
我的结论是创建一个自定义字段
- 非表单标签中的名称(跨度)
- 隐藏输入中的 id
但在这种情况下我不知道如何实现它。
我的用户实体:
class User extends BaseUser
{
...
public function __toString()
{
return ($this->lastName . " " . $this->firstName. " [".$this->getId()."]");
}
}
我的注册实体:
class Registration
{
/**
* @var \MyBundle\Entity\User
*
* @ORM\ManyToOne(targetEntity="MyBundle\Entity\User")
* @ORM\JoinColumns({
* @ORM\JoinColumn(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' => 'MyBundle\Entity\User',
]);
}
}
我有一个 select 显示用户名和 id 作为值。最大的问题是人体工程学:我可能有几千个用户。我无法显示那么大的列表。
所以我想到了一个自动完成字段。
$builder
->add('user', TextType::class, [
'label' => 'user.name',
'attr' => [
'class' => 'reguser userpicker',
],
]);
这里的问题是多方面的: 在自动完成字段中,我显然显示了名称(最终用户搜索的是名称,而不是 ID)但是当我保存时这将毫无用处,因为我需要用户 ID。
所以我开始玩弄自动完成 js 以在额外的范围内显示名称,并用 id 替换自动完成的值。这是 hacky 并且不可用,因为当我编辑时,我在文本字段中显示了来自用户的 __toString() 值。
实现此目的的一种方法是在您的字段中添加 DataTransformer
。
完整文档可用here。
1.创建您的 DataTransformer
此 class 会将您的用户名(字符串)转换为 User
。
namespace AppBundle\Form\DataTransformer;
// your User class :
use AppBundle\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;
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 作为参数,或者使用正确的参数将 UsernameToUserTransformer 声明为服务
$builder
->add('user', EntityType::class, [
'label' => 'user.name',
'attr' => [
'class' => 'reguser',
],
'class' => 'MyBundle\Entity\User',
]);
$builder
->get('user')
->addModelTransformer(new UsernameToUserTransformer($this->em))
;