我遇到了以下问题。
我正在使用Symfony 4.2.3来构建一个论坛(一个更大的项目)
我做了一个处理的ForumController:
我想要的是实现一个编辑按钮,该按钮不会重定向到编辑页面,而是$(this).slidedown在div中的编辑表单。仅当ForumMessage作者是当前登录用户时,才会显示此按钮。因此,如果该用户有很多时间回复该主题,我需要尽可能多的按钮(和表单)。点击编辑后,页面可以重新加载和实体更新。
对于使用重定向创建/编辑我已经理解了如何。
问题是,如何处理未知数量的编辑MessageType表单(以及未知的表单id)。
我尝试创建一个ForumMessage数组的链接到MessageType Form数组。但是当我必须将每个表单的.createView()赋予树枝时,我的大脑才会出现故障。
那么请问,我怎样才能在单个页面上有很多编辑表单(每个链接到被引用的实体)并在我的控制器中处理它们以进行.flush修改?
我已经为按钮和链接div的diplaying实现了JS函数。
我的ForumController.php的showTopic方法:
/**
* @Route("/forum/category={idCategory}/subCategory={idSubCategory}/topic={idTopic}", name="topic")
* @ParamConverter("topic", options={"id" = "idTopic"})
* @param $idCategory
* @param $idSubCategory
* @param $idTopic
* @param Request $request
* @param ObjectManager $manager
* @param UserInterface $user
* @return \Symfony\Component\HttpFoundation\Response
* @throws \Exception
*/
public function showTopic($idCategory, $idSubCategory, $idTopic, Request $request, ObjectManager $manager, UserInterface $user = null) {
$topic = $this->getDoctrine()->getRepository(ForumTopic::class)->find($idTopic);
$userMessages = $this->getDoctrine()->getRepository(ForumMessage::class)->findBy([
'author' => "Kaarie",
'forumTopic' => $topic
]);
// Nouveau message sur un topic
$message = new ForumMessage();
$form = $this->createForm(ForumMessageType::class, $message);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()) {
$message->setAuthor($user->getUsername())
->setCreatedAt(new \DateTime())
->setForumTopic($topic);
$manager->persist($message);
$manager->flush();
return $this->redirectToRoute('topic', [
'idCategory' => $idCategory,
'idSubCategory' => $idSubCategory,
'idTopic' => $topic->getId(),
]);
}
// Editer un message
$editMessage = new ForumMessage();
$editForm = $this->createForm(ForumMessageType::class, $editMessage);
$editForm->handleRequest($request);
if($editForm->isSubmitted() && $editForm->isValid()) {
$manager->persist($editMessage);
$manager->flush();
return $this->redirectToRoute('topic', [
'idCategory' => $idCategory,
'idSubCategory' => $idSubCategory,
'idTopic' => $topic->getId(),
]);
}
return $this->render('forum/showTopic.html.twig',[
'idCategory' => $idCategory,
'idSubCategory' => $idSubCategory,
'topic' => $topic,
'messageForm' => $form->createView(),
'editForm' => $editForm->createView(),
'userMessage' => $userMessages,
]);
}
MessageType.php中的MessageType类
class ForumMessageType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('content')
->add('submit', SubmitType::class)
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => ForumMessage::class,
]);
}
}
从showTopic.html.twig显示消息的树枝部分
<ul>
{% for message in topic.ForumMessages %}
<li>
{{ message.author }},</br>
{{ message.content }}
{% if app.user %}
{% if is_granted("ROLE_MODERATOR") %}
<button>Moderate</button> {# TODO: moderation d'un message #}
{% endif %}
{% if app.user.username == message.author %}
<div class="alert alert-danger" style="margin: 1em; display: none">
<h3>Etidé votre réponse :</h3>
{{ form_start(editForm) }}
{{ form_row(editForm.content) }}
{{ form_row(editForm.submit, {'label': 'Editer'}) }}
{#<button type="submit" class="btn btn-primary">Editer</button>#}
{{ form_end(editForm) }}
</div>
<button id="buton_EditTopic">Modifier</button>
{% endif %}
{% endif %}
</li>
{% endfor %}
</ul>
对于任何其他资源,请问我!
我的方法是(可能需要一些调整,没有测试)
简写说明:该列表仅包含容器。编辑一条消息时,只加载表单并将其推送到此特定容器。如果你编辑它并按保存,它会将每个ajax请求的表单发送给控制器。如果表单有效,它将返回一个json repsonse而不是html ...
控制器:
/**
* @Route("/forum/category={idCategory}/subCategory={idSubCategory}/topic={idTopic}", name="topic")
* @ParamConverter("topic", options={"id" = "idTopic"})
* @param $idCategory
* @param $idSubCategory
* @param $idTopic
* @param Request $request
* @return \Symfony\Component\HttpFoundation\Response
* @throws \Exception
*/
public function showTopic(
$idCategory,
$idSubCategory,
$idTopic,
Request $request,
ObjectManager $manager,
UserInterface $user = null
)
{
$topic = $this->getDoctrine()->getRepository(ForumTopic::class)->find($idTopic);
$userMessages = $this->getDoctrine()->getRepository(ForumMessage::class)->findBy([
'author' => "Kaarie",
'forumTopic' => $topic
]);
return $this->render('forum/showTopic.html.twig',[
'idCategory' => $idCategory,
'idSubCategory' => $idSubCategory,
'topic' => $topic,
'userMessage' => $userMessages,
]);
}
/**
* With this, you can create and mod Topics
* @Route("/forum/messages/{forumMessage}/mod-message", name="message.mod", defaults={"forumMessage":0})
* @IsGranted("ROLE_USER")
* @param Request $request
* @param ForumMessage $forumMessage
* @return mixed
*/
public function modTopic(
Request $request,
Objectmanager $manager,
ForumMessage $forumMessage=null
)
{
if($formMessage == null) {
$forumMessage = new ForumMessage();
/* set Additional Info here, maybe User, IP Adress or whatever */
}
$editForm = $this->createForm(ForumMessageType::class, $forumMessage);
$editForm->handleRequest($request);
if($editForm->isSubmitted() && $editForm->isValid()) {
$manager->persist($forumMessage);
$manager->flush();
return new JsonRepsonse(['status'=>true, 'message' => "ForumMessage save successfull"]);
}
return $this->render('mod.message.html.twig',[
'messageForm' => $editForm->createView(),
]);
}
FormType:
class ForumMessageType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('content')
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => ForumMessage::class,
]);
}
}
list.html.twig
<ul>
{% for message in topic.ForumMessages %}
<li>
{{ message.author }},</br>
{{ message.content }}
{% if app.user %}
{% if is_granted("ROLE_MODERATOR") %}
<button>Moderate</button> {# TODO: moderation d'un message #}
{% endif %}
{% if app.user.username == message.author %}
<div id="modMessageContainer{{ message.id }}" class="alert alert-danger" style="margin: 1em; display: none">
</div>
<button onclick="modMessage(this);"
data-attr-url="{{ path('message.mod'.{'forumMessage':message.id}) }}"
data-attr-container="#modMessageContainer{{ message.id }}"
>Modifier</button>
{% endif %}
{% endif %}
</li>
{% endfor %}
</ul>
<script>
function modMessage(element)
{
$.ajax({
url: $(element).attr('data-attr-url'),
success: function(data) {
$($(element).attr('data-attr-container')).html(data).show();
}
});
}
function saveMessage(element)
{
var container = $(element).attr('data-attr-container');
$.ajax({
url: $(element).attr('data-attr-url'),
type:'POST',
data: $(container +' form').serialize(),
success: function(data) {
if(typeof data == 'object' && data instanceof Object && !(data instanceof Array)) {
if(data.status) {
location.reload()
} else {
alert(data.message);
}
} else {
$(container).show();
$('#modMessage').replaceWith($(data).find('#modMessage'));
}
}
});
}
</script>
mod.html.twig
<div>
<div id="modMessage">
<h3>Etidé votre réponse :</h3>
{{ form_start(editForm) }}
{{ form_row(editForm.content) }}
{{ form_row(editForm.submit, {'label': 'Editer'}) }}
{#<button type="submit" class="btn btn-primary">Editer</button>#}
{{ form_end(editForm) }}
<div style="text-align:right">
<button onclick="saveMessage(this);"
type="button"
class="btn btn-success"
data-attr-container="modMessageContainer{{ message.id }}"
data-attr-url="{{ path('message.mod', {'forumMessage':message.id}) }}"
>Save</button>
</div>
</div>
</div>