在 Remix 中获取 ag-grid 的数据

发布于 2025-01-16 19:57:49 字数 450 浏览 2 评论 0原文

我正在学习 Remix.run 并试图找出如何面对一些要求 提前。根据文档,有一个名为 资源路由 的东西。但似乎资源路由需要从链接组件链接:

<Link to="pdf" reloadDocument>
    View as PDF
</Link>

我找不到任何示例来展示如何创建可以返回网格组件数据的简单路由,例如 ag-grid 。

有什么方法可以在 Remix 中执行此操作,或者我需要实现外部端点?

I'm learning Remix.run and trying to figure out how to face some requirements
in advance. According to the documentation there is something called Resource Routes. But seems that a Resource Route need to be linked from a Link component:

<Link to="pdf" reloadDocument>
    View as PDF
</Link>

I can't found any example showing how to create a simple route that can return data for a grid component, for example ag-grid.

There is any way to do this inside Remix or I will need to implement an external endpoint?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

残花月 2025-01-23 19:57:49

AG Grid 不久前写了一篇关于此的博客文章。这是文章: https:// blog.ag-grid.com/using-ag-grid-react-ui-with-remix-run/

首先,使用此处概述的 Remix 约定设置资源路由: https://remix.run/docs/en/v1/guides/resource-routes#creating-resource-routes

资源路由应该只导出一个加载器函数来检索您想要的数据加载到表中。

注意:此示例还使用无限滚动的逻辑

app/routes/posts/$id/postsGridData.ts

import type { LoaderFunction } from 'remix';
import { db } from '~/utils/db.server'; // Prisma ORM being used

export const loader: LoaderFunction = ({ request }) => {
  const from = Number(new URL(request.url).searchParams.get("from"));
  const to = Number(new URL(request.url).searchParams.get("to"));

  if (from >= 0 && to > 0) {
    const posts = await db.post.findMany({
      skip: from,
      take: to - from,
      select: {
        id: true,
        title: true,
        updatedAt: true,
        author: {
          select: {
            email: true,
            name: true,
          },
        },
      },
    });

    return posts;
  }
  return [];
}

接下来,在包含 AGGridReact 组件的路由中,您将添加以下内容:

  • 一个 Remix Fetcher,用于在不更改路由的情况下从资源路由获取数据
  • 一个 onGridReady 函数,用于加载下一批数据
  • 一些本地状态来管理获取逻辑
  • 一个 datasource代码>插入 AG Grid
  • 当 fetcher 加载
  • 带有添加参数 rowModelTypeonGridReady

app/routes 的 AgGridReact 组件时触发的 useEffect 函数/posts.tsx

import { useFetcher } from 'remix';
import { useCallback, useEffect, useState } from 'react';
import { AgGridReact } from "ag-grid-react";
import AgGridStyles from "ag-grid-community/dist/styles/ag-grid.css";
import AgThemeAlpineStyles from "ag-grid-community/dist/styles/ag-theme-alpine.css";

export default function PostsRoute() {
  const [isFetching, setIsFetching] = useState(false);
  const [getRowParams, setGetRowParams] = useState(null);
  const posts = useFetcher();
  
  const onGridReady = useCallback((params) => {
    const datasource = {
    getRows(params) {
      if (!isFetching) {
        posts.load(`/posts?from=${params.startRow}&to=${params.endRow}`);

        setGetRowParams(params);
        setIsFetching(true);
      }
    },
  };

  params.api.setDatasource(datasource);
  }, []);

  useEffect(() => {
  // The useEffect hook in this code will trigger when the fetcher has 
  // loaded new data. If a successCallback is available, it’ll call it, 
  // passing the loaded data and the last row to load
  if (getRowParams) {
    const data = posts.data || [];

    getRowParams.successCallback(
      data,
      data.length < getRowParams.endRow - getRowParams.startRow
        ? getRowParams.startRow
        : -1
    );
  }

  setIsFetching(false);
  setGetRowParams(null);
}, [posts.data, getRowParams]);

  const columnDefs = [/* Your columnDefs */];

  return (
    <div className="ag-theme-alpine" style={{ width: "100%", height: "100%" }}>
      <AgGridReact
        columnDefs={columnDefs}
        rowModelType="infinite"
        onGridReady={onGridReady}
      />
    </div>
  );
}

AG Grid wrote a blog post about this not too long ago. Here is the article: https://blog.ag-grid.com/using-ag-grid-react-ui-with-remix-run/.

First, set up a resource route using Remix's conventions outlined here: https://remix.run/docs/en/v1/guides/resource-routes#creating-resource-routes

The resource route should export only a loader function that retrieves the data you want to load into the table.

Note: This example also uses logic for infinite scrolling

app/routes/posts/$id/postsGridData.ts

import type { LoaderFunction } from 'remix';
import { db } from '~/utils/db.server'; // Prisma ORM being used

export const loader: LoaderFunction = ({ request }) => {
  const from = Number(new URL(request.url).searchParams.get("from"));
  const to = Number(new URL(request.url).searchParams.get("to"));

  if (from >= 0 && to > 0) {
    const posts = await db.post.findMany({
      skip: from,
      take: to - from,
      select: {
        id: true,
        title: true,
        updatedAt: true,
        author: {
          select: {
            email: true,
            name: true,
          },
        },
      },
    });

    return posts;
  }
  return [];
}

Next, in the route with your AGGridReact component, you'll add the following:

  • A Remix Fetcher to get the data from your resource route without a route change
  • An onGridReady function that loads the next batch of data
  • Some local state to manage the fetching logic
  • A datasource to plug into AG Grid
  • A useEffect function to trigger when the fetcher has loaded
  • AgGridReact component with added parameters rowModelType and onGridReady

app/routes/posts.tsx

import { useFetcher } from 'remix';
import { useCallback, useEffect, useState } from 'react';
import { AgGridReact } from "ag-grid-react";
import AgGridStyles from "ag-grid-community/dist/styles/ag-grid.css";
import AgThemeAlpineStyles from "ag-grid-community/dist/styles/ag-theme-alpine.css";

export default function PostsRoute() {
  const [isFetching, setIsFetching] = useState(false);
  const [getRowParams, setGetRowParams] = useState(null);
  const posts = useFetcher();
  
  const onGridReady = useCallback((params) => {
    const datasource = {
    getRows(params) {
      if (!isFetching) {
        posts.load(`/posts?from=${params.startRow}&to=${params.endRow}`);

        setGetRowParams(params);
        setIsFetching(true);
      }
    },
  };

  params.api.setDatasource(datasource);
  }, []);

  useEffect(() => {
  // The useEffect hook in this code will trigger when the fetcher has 
  // loaded new data. If a successCallback is available, it’ll call it, 
  // passing the loaded data and the last row to load
  if (getRowParams) {
    const data = posts.data || [];

    getRowParams.successCallback(
      data,
      data.length < getRowParams.endRow - getRowParams.startRow
        ? getRowParams.startRow
        : -1
    );
  }

  setIsFetching(false);
  setGetRowParams(null);
}, [posts.data, getRowParams]);

  const columnDefs = [/* Your columnDefs */];

  return (
    <div className="ag-theme-alpine" style={{ width: "100%", height: "100%" }}>
      <AgGridReact
        columnDefs={columnDefs}
        rowModelType="infinite"
        onGridReady={onGridReady}
      />
    </div>
  );
}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文