使用上下文过滤器在 Drupal 8 中加载视图的理想方式

问题描述 投票:0回答:1

我有一个名为类别的分类法。

我有一个菜单,其中包含指向每个分类项的链接。

每个项目的分类页面都有该菜单,还包含一个视图,该视图使用 URL 中的上下文过滤器将视图的内容过滤为具有该分类术语的内容。

我想在单击这些菜单项之一时使用 Ajax 加载视图内容。

通过在视图上启用 ajax 并使用以下 JavaScript,我已经能够达到预期的结果。

(function ($) {
  Drupal.behaviors.course_browser = {
    attach: function (context, settings) {
      // should only be one menu, but guard against 0, and avoid the if statement.
      context.querySelectorAll(".menu--categories").forEach((menu) => {
        // for each link in the menu
        menu.querySelectorAll(".nav-link").forEach((link) => {
          // on click
          link.addEventListener("click", (event) => {
            event.preventDefault();

            // fetch the taxonomy term id from menu link
            let tid = event.target.dataset.drupalLinkSystemPath.replace(
              "taxonomy/term/",
              ""
            );

            // make the ajax call
            $.ajax({
              url: "/views/ajax",
              type: "post",
              data: {
                view_name: "course_browser",
                view_display_id: "block_1",
                view_args: tid,
              },
              success: (response) => {
                response.forEach((action) => {
                  // the response contains a number of commands; I'm not sure
                  if (
                    action.command === "insert" &&
                    action.method === "replaceWith"
                  ) {
                    let viewElement = document.querySelector(VIEW_SELECTOR);

                    // update the html of the course browser
                    viewElement.innerHTML = action.data;

                    // update the url in the browser
                    window.history.pushState("", "", event.target.href);

                    // seperate function to adjust my page title
                    updatePageTitle(event.target.textContent);

                    // call drupal behaviours passing context to ensure all the other js code gets a chance to manipulate the new content
                    Drupal.attachBehaviors(viewElement);
                  }
                });
              },
              error: function (data) {
                console("An error occured fetching the course browser");
              },
            });
          });
        });
      });
    },
  };
})(jQuery);

我在这里寻找有关我的方法的反馈;我现在主要关心的是我处理回复的方式。当我查看回复时,我收到如下所示的内容:

0: {command: "settings", settings: {…}, merge: true}
1: {command: "add_css", data: "<link rel="stylesheet" media="all" href="/core/modules/views/css/views.module.css?qcog4i" />↵"}
2: {command: "insert", method: "append", selector: "body", data: "<script src="/core/assets/vendor/jquery/jquery.min…/js/modules/views/ajax_view.js?qcog4i"></script>↵", settings: null}
3: {command: "insert", method: "replaceWith", selector: ".js-view-dom-id-", data: "The HTML"}

如您所见,我通过挑选我想要的部分并替换视图的 HTML 来手动处理响应。根据我在 Drupal 周围看到的情况,我认为应该有一些我可以将此响应传递给自动处理的东西。当我查看浏览器的 window 对象时,我可以看到 Drupal.AjaxCommands 看起来它是为处理这个问题而设计的,但我不确定我应该如何使用它。

我还注意到,在这种情况下,我可以简单地将此响应传递给执行这些 AjaxCommand 的东西,选择器“.js-view-dom-id-”是不正确的。所以我可以在传递之前调整响应,或者如果有人知道调整 ajax 请求以获得正确选择器的方法,那将是理想的。

抱歉,如果这个信息在某个地方很容易获得......周围有一些与 Drupal 和 Ajax 相关的资源,但我无法找到我在这里所做的事情的例子,情况似乎总是不同我不能使用它们。

感谢您的帮助。

ajax drupal
1个回答
0
投票

我正在尝试做类似的事情。事实证明,Drupal 有一个辅助方法

commandExecutionQueue
编写来处理来自 Ajax 响应的所有命令。

参见:https://drupaljs.net/9.5.x/Drupal.Ajax.html

例子:

const url = "/views/ajax";
const data = {
  view_name: "course_browser",
  view_display_id: "block_1",
  view_args: tid
};

const ajax = new Drupal.Ajax(false, false, {
  url: url,
  submit: data,
  success: function(response, status) {
    ajax.commandExecutionQueue(response, status);
  }
});
ajax.execute();

注意:我上面发布的 API 文档适用于 Drupal 9.5+。我不知道这是否适用于 Drupal 8。值得一试。

© www.soinside.com 2019 - 2024. All rights reserved.