Drupal8中如何实现评论提交后不刷新页面且停留在当前节点
嘿,这个需求我在Drupal 8项目里刚好处理过,给你两个靠谱的解决方案,都是亲测能解决问题的:
方案1:通过自定义模块修改表单提交逻辑(推荐,更稳定)
首先你得有个自定义模块(没有的话快速建一个就行),然后在模块的.module文件里加下面的代码:
/** * Implements hook_form_alter(). */ function your_custom_module_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) { // 匹配评论表单的ID,Drupal 8里评论表单ID是类似comment_node_article_form这种格式 if (strpos($form_id, 'comment_node_') !== FALSE && strpos($form_id, '_form') !== FALSE) { // 给表单加自定义的提交处理函数 $form['actions']['submit']['#submit'][] = 'your_custom_module_comment_submit_handler'; // 开启AJAX提交,实现无刷新 $form['#ajax'] = [ 'callback' => 'your_custom_module_comment_ajax_callback', 'wrapper' => 'comments-container', // 这个ID要和你节点模板里的评论容器对应 'method' => 'replace', 'effect' => 'fade', ]; } } /** * 自定义提交处理,修改重定向逻辑 */ function your_custom_module_comment_submit_handler(&$form, \Drupal\Core\Form\FormStateInterface $form_state) { // 获取当前节点对象 $comment_entity = $form_state->getFormObject()->getEntity(); $node = $comment_entity->get('entity_id')->entity; // 重定向回原节点,不带评论锚点 $form_state->setRedirectUrl($node->toUrl()); } /** * AJAX回调:返回更新后的评论区域 */ function your_custom_module_comment_ajax_callback(&$form, \Drupal\Core\Form\FormStateInterface $form_state) { $comment_entity = $form_state->getFormObject()->getEntity(); $node = $comment_entity->get('entity_id')->entity; // 加载并渲染节点的所有评论 $comments = \Drupal::entityTypeManager() ->getViewBuilder('comment') ->viewMultiple($node->getComments(), 'default'); return $comments; }
接下来要修改你的节点模板(比如node.html.twig),把评论区域包在一个指定ID的容器里,这样AJAX才能正确替换内容:
<div id="comments-container"> {{ content.comments }} </div>
方案2:前端JS拦截表单提交(快速实现,适合不想碰后端的情况)
如果你不想写后端模块,用前端JS也能搞定。首先在你的主题js目录下创建comment-submit-handler.js,然后在主题的libraries.yml里配置引入:
comment-submit-handler: js: js/comment-submit-handler.js: {} dependencies: - core/jquery - core/drupal - core/drupal.ajax
然后在主题的.info.yml里把这个库加上:
libraries: - your_theme/comment-submit-handler
最后写JS逻辑:
(function ($, Drupal) { Drupal.behaviors.preventCommentRedirect = { attach: function (context, settings) { // 找到所有评论表单,只绑定一次事件 $('form[id^="comment-node-"]', context).once('prevent-comment-redirect').submit(function (e) { // 阻止默认的表单提交跳转 e.preventDefault(); const $form = $(this); // 用Drupal的AJAX API提交表单 Drupal.ajax({ url: $form.attr('action'), type: 'POST', data: $form.serialize(), success: function () { // 提交成功后刷新评论区域 const $commentContainer = $('#comments-container'); if ($commentContainer.length) { // 重新加载评论区域内容 $commentContainer.load(window.location.href + ' #comments-container > *'); } // 重置表单 $form[0].reset(); } }).execute(); }); } }; })(jQuery, Drupal);
一些注意点
- 不管用哪种方法,都要确保用户有评论提交的权限,不然白忙活
- 如果是用Views展示评论的话,AJAX回调里要改成渲染对应的View,而不是默认的评论视图
- 测试匿名用户提交的情况,确保CSRF令牌正常工作,不然表单会提交失败
内容的提问来源于stack exchange,提问作者techmech
相关产品推荐
相关产品推荐

