情景
我有两个与manyToMany
关系链接在一起的实体。
实体
User
Interest
因此,在用户的个人资料表单中,有一个名为Interests
的字段,使用select2呈现。
现在,用户可以根据需要选择任意数量的兴趣,并且在保存原则时,可以很好地将所选兴趣保存在链接表中。当我重新加载个人资料页面时,我可以看到我已经选择的兴趣。
问题
虽然表单字段与Interest
实体
$form->add('interest', EntityType::class, array(
'class' => 'AppBundle\Entity\Interest',
'multiple' => true,
'expanded' => false,
'by_reference' => false)
用户还可以在前端和后端Tagging Support的帮助下添加Interest
表中不存在的自己的兴趣,以保存我Form Event Subscriber所拥有的信息检查用户提交的任何兴趣是否存在于Interest
表中的地方添加它们并且它在这里我得到以下异常
Message
This value is not valid.
Origin
interest
Cause
Symfony\Component\Validator\ConstraintViolation
Object(Symfony\Component\Form\Form).children[interest] = [0 => 1, 1 => 4, 2 => 7, 3 => www]
Caused by:
Symfony\Component\Form\Exception\TransformationFailedException
Unable to reverse value for property path "interest": Could not find all matching choices for the given values
Caused by:
Symfony\Component\Form\Exception\TransformationFailedException
Could not find all matching choices for the given values
以下是事件订阅者代码
namespace AppBundle\Form\EventListener;
use AppBundle\Entity\Interest;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
class AddProfileFieldSubscriber implements EventSubscriberInterface
{
protected $authorizationChecker;
protected $em;
function __construct(AuthorizationChecker $authorizationChecker, EntityManager $em)
{
$this->authorizationChecker = $authorizationChecker;
$this->em = $em;
}
public static function getSubscribedEvents()
{
// Tells the dispatcher that you want to listen on the form.pre_set_data
// event and that the preSetData method should be called.
return array(
FormEvents::PRE_SUBMIT => 'onPreSubmit'
);
}
/**
* @param FormEvent $event
*/
public function onPreSubmit(FormEvent $event){
$interestTags = $event->getData();
$interestTags = $interestTags['interest'];
foreach($interestTags as $interestTag){
$interest = $this->em->getRepository('AppBundle:Interest')->findOneBy(array('id' => $interestTag));
if(!$interest){
$newInterest = new Interest();
$newInterest->setName($interestTag);
$this->em->persist($newInterest);
$this->em->flush();
}
}
}
}
尝试
我通过添加choice_value
$form->add('interest', EntityType::class, array(
'class' => 'AppBundle\Entity\Interest',
'multiple' => true,
'expanded' => false,
'by_reference' => false,
'choice_value' => 'name'
)
);
我从
更改了事件订阅者中的查询$interest = $this->em->getRepository('AppBundle:Interest')->findOneBy(array('id' => $interestTag));
到
$interest = $this->em->getRepository('AppBundle:Interest')->findOneBy(array('name' => $interestTag));
这首先完美无缺,但是当我重新加载个人资料页面时,我的兴趣字段显示为空
它显得空的原因是因为(我的假设)id="select2-user_interest-result-5z18-Education"
我认为需要看起来像id="select2-user_interest-result-5z18-66"
<ul class="select2-results__options" role="tree" aria-multiselectable="true" id="select2-user_interest-results"
aria-expanded="true" aria-hidden="false">
<li class="select2-results__option" id="select2-user_interest-result-5z18-Education" role="treeitem"
aria-selected="false">Education
</li>
<li class="select2-results__option" id="select2-user_interest-result-rdka-History" role="treeitem"
aria-selected="false">History
</li>
<li class="select2-results__option select2-results__option--highlighted"
id="select2-user_interest-result-lfq4-Architecture" role="treeitem" aria-selected="false">Architecture
</li>
<li class="select2-results__option" id="select2-user_interest-result-qqiq-Entrepreneurship" role="treeitem"
aria-selected="false">Entrepreneurship
</li>
<li class="select2-results__option" id="select2-user_interest-result-qutx-Technology" role="treeitem"
aria-selected="false">Technology
</li>
<li class="select2-results__option" id="select2-user_interest-result-sfx4-Engineering" role="treeitem"
aria-selected="false">Engineering
</li>
我交叉检查了兴趣表中的数据,我可以看到用户添加的新兴趣之前不存在,所以它的工作但在前端没有显示。出于好奇,我删除了choice_value
,然后重新加载了个人资料页面,我可以看到新的兴趣
如果有任何事情可以让我朝着正确的方向前进并让我知道我错过了什么以及如何让它发挥作用,我将非常感激。
答案 0 :(得分:0)
您无法以EntityType
扩展ChoiceType
来执行此操作,但不允许在选项列表中添加新值。
您应该在食谱http://symfony.com/doc/current/cookbook/form/form_collections.html
中使用CollectionType
要在代码中进行正确的选择,您还必须在视图中插入所有兴趣的完整列表以及表单。
然后你的观点应该是:
<select name='{{ form.interest.vars.full_name }}' id="{{ form.interest.vars.id }}" class='select2'>
{% for interestList as interestItem %}
<option value='{{ interestItem.id }}' {% if some_logic_to_check_whether_the_item_is_selected %}selected='selected'{% endif %} >{{ interestItem.name }}</option>
{% endfor %}
</select>