Symfony 表单:集合 - 只需添加新条目/防止修改旧条目
Symfony Forms: Collection - Just Add New Entries / Prevent Modifying Old Entries
我在我的项目中遇到了问题,但真的不知道如何解决。也许我的做法是完全错误的,我应该换个方向。
我有两个实体:文章和文章评论
在我的 ArticleType 中,我添加了带有 CollectionType 的 Comments(这样做的主要原因是我还想修改 Article - 主要是更改 Article 内容并且还能够添加 1 条评论):
//ArticleType.php
$builder->add('articleComments', CollectionType::class, ['label' => false, 'entry_type' => AritcleCommentType::class, 'entry_options' => ['label' => false]]);
我的 ArticleCommentType 只是一个文本区域字段:
//ArticleCommentType.php
$builder->add('text', TextareaType::class, ['label' => 'comment', 'required' => false, 'attr' => ['class' => 'textarea-sm']]);
这个解决方案非常适合我。
但是,每当我添加评论时,我的其他评论也会呈现在文本区域字段中并且可以编辑,这是我不想要的。我只是希望用户添加 1 条评论,重新加载页面,然后再添加一条评论即可。
我已经尝试阻止呈现其他评论,但这会引发错误,因为该元素已不在 DOM 中 - 但仍在预期中。
有什么解决办法吗? (隐藏字段对我来说不是有效的解决方案)
更新:
我的控制器:
//ArticleController.php
...
/**
* @Route("/article/{id}", name="app_article", requirements={"id"="\d+"})
*/
public function article(Request $request, Article $article)
{
$articleComment = new ArticleComment();
$article->addArticleComment($articleComment);
$form = $this->createForm(ArticleType::class, $article);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($articleComment); //cascade not active
$em->persist($article);
$em->flush();
$this->addFlash('success', 'entry_saved');
return $this->redirectToRoute('app_article', ['id' => $article->getId()]);
}
return $this->render('article/view.html.twig', ['article' => $article, 'form' => $form->createView()]);
}
...
更改文章类型:
$builder->add('articleComments', ArticleCommentType::class, ['label' => false, 'data' => new ArticleComment()]); //changed as suggested
只要你用
$builder
->add('articleComments', CollectionType::class, [
'label' => false,
'entry_type' => AritcleCommentType::class,
'entry_options' => ['label' => false],
'mapped' => false,
]);
您将渲染整个集合。
对我来说,最合适的解决方案是直接将 ArticleCommentType
和 data
属性设置添加到 new ArticleComment
。
如果你想显示所有评论,你应该直接在模板中传递所有现有的 ArticleComment
显示你需要显示的内容。
您唯一需要注意的是将全新元素(如果有任何值)手动添加(可能在表单订阅者中)到现有集合中。
我在我的项目中遇到了问题,但真的不知道如何解决。也许我的做法是完全错误的,我应该换个方向。
我有两个实体:文章和文章评论
在我的 ArticleType 中,我添加了带有 CollectionType 的 Comments(这样做的主要原因是我还想修改 Article - 主要是更改 Article 内容并且还能够添加 1 条评论):
//ArticleType.php
$builder->add('articleComments', CollectionType::class, ['label' => false, 'entry_type' => AritcleCommentType::class, 'entry_options' => ['label' => false]]);
我的 ArticleCommentType 只是一个文本区域字段:
//ArticleCommentType.php
$builder->add('text', TextareaType::class, ['label' => 'comment', 'required' => false, 'attr' => ['class' => 'textarea-sm']]);
这个解决方案非常适合我。
但是,每当我添加评论时,我的其他评论也会呈现在文本区域字段中并且可以编辑,这是我不想要的。我只是希望用户添加 1 条评论,重新加载页面,然后再添加一条评论即可。
我已经尝试阻止呈现其他评论,但这会引发错误,因为该元素已不在 DOM 中 - 但仍在预期中。
有什么解决办法吗? (隐藏字段对我来说不是有效的解决方案)
更新:
我的控制器:
//ArticleController.php
...
/**
* @Route("/article/{id}", name="app_article", requirements={"id"="\d+"})
*/
public function article(Request $request, Article $article)
{
$articleComment = new ArticleComment();
$article->addArticleComment($articleComment);
$form = $this->createForm(ArticleType::class, $article);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($articleComment); //cascade not active
$em->persist($article);
$em->flush();
$this->addFlash('success', 'entry_saved');
return $this->redirectToRoute('app_article', ['id' => $article->getId()]);
}
return $this->render('article/view.html.twig', ['article' => $article, 'form' => $form->createView()]);
}
...
更改文章类型:
$builder->add('articleComments', ArticleCommentType::class, ['label' => false, 'data' => new ArticleComment()]); //changed as suggested
只要你用
$builder
->add('articleComments', CollectionType::class, [
'label' => false,
'entry_type' => AritcleCommentType::class,
'entry_options' => ['label' => false],
'mapped' => false,
]);
您将渲染整个集合。
对我来说,最合适的解决方案是直接将 ArticleCommentType
和 data
属性设置添加到 new ArticleComment
。
如果你想显示所有评论,你应该直接在模板中传递所有现有的 ArticleComment
显示你需要显示的内容。
您唯一需要注意的是将全新元素(如果有任何值)手动添加(可能在表单订阅者中)到现有集合中。