在ag-grid内渲染svelte组件

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

有人有如何在 ag 网格内渲染 svelte 组件的示例吗? 类似于如何在 ag-grid 中渲染 angularjs 或 React 组件。

ag-grid svelte
3个回答
5
投票

只是为了添加@ben-sewards 答案,我想出了一个工厂函数,使我可以更轻松地嵌入随机组件。

    /**
     * Base class for embedding a svelte component within an AGGrid call.
     * See: https://stackoverflow.com/a/72608215
     */
    import type {
      ICellRendererComp,
      ICellRendererParams
    } from "ag-grid-community";

    /**
     * Class for defining a cell renderer.
     * If you don't need to define a separate class you could use cellRendererFactory 
     * to create a component with the column definitions.
     */
    export abstract class AbstractCellRenderer implements ICellRendererComp {

      eGui: any
      protected value: any

      constructor(parentElement = "span") {
        // create empty span (or other element) to place svelte component in
        this.eGui = document.createElement(parentElement);
      }

      init(params: ICellRendererParams) {
        this.value = params.value;
        this.createComponent(params);
      }

      getGui() {
        return this.eGui;
      }

      refresh(params: ICellRendererParams) {
        this.value = params.value;
        this.eGui.innerHTML = '';

        return true;
      }

      /**
       * Define and create the svelte component to use in the cell
       * @example
       * // This is all you need to do within this method: create the component with new, specify the target
       * // is the class, and pass in props via the params.
       * new CampusIcon({
       *    target: this.eGui,
       *    props: {
       *        color: params.data?.color,
       *        name: params.data?.name
       * }
       * @param params params for rendering the call, including the value for the cell
       */
      abstract createComponent(params: ICellRendererParams): void
    }

    /**
     * Creates a cell renderer using the given callback for how to initialise a svelte component.
     * See AbstractCellRenderer.createComponent
     * @param svelteComponent function for how to create the svelte component
     * @returns 
     */
    export function cellRendererFactory(svelteComponent: (cell: AbstractCellRenderer, params: ICellRendererParams) => void) {
      class Renderer extends AbstractCellRenderer {
        createComponent(params: ICellRendererParams < any, any > ): void {
          svelteComponent(this, params)
        }
      }
      return Renderer;
    }

然后对于列定义,像这样使用它:

    import CampusIcon from '$lib/components/campus/CampusIcon.svelte';


    const columnDefs = [
        {
            field: 'campusId',
            cellRenderer: cellRendererFactory((c, p) => {
                new CampusIcon({
                    target: c.eGui,
                    props: {
                        color: p.data?.color,
                        name: p.data?.name
                    }
                });
            }),
            headerName: 'Campus',
        }
    ]

3
投票

由于 AG-Grid 没有 Svelte 扩展,您可能必须使用 Svelte 客户端组件 API 来处理此问题。

编辑:下面经过测试的工作方法

创建 CellRenderer

import SiteAccountCellButtonSvelte from "./SiteAccountCellButton.svelte";

export class SiteAccountButtonRenderer {
  constructor() {
    // create empty div to place svelte component in
    this.eGui = document.createElement("div");
  }

  init(params: ICellRendererParams) {
    this.value = params.value;

    new SiteAccountCellButtonSvelte({
      target: this.eGui,
      props: {
        // your props here
        siteBalance: params.data,
      },
    });
  }

  getGui() {
    return this.eGui;
  }

  refresh(params) {
    this.value = params.value;
    this.eGui.innerHTML = '';

    return true;
  }
}

配置 AG-Grid 选项

const gridOptions: GridOptions = {
  pagination: true,
  paginationPageSize: 15,
  domLayout: "autoHeight",
  rowHeight: 56,
  defaultColDef: {
    sortable: true,
    unSortIcon: true,
    resizable: true,
    flex: 1,
    minWidth: 170,
  },
  columnDefs: [
    {
      headerName: "account name",
      field: "accountName",
      filter: true,
      floatingFilter: true,
      cellClass: (_params: CellClassParams) => {
        return "fw-bold";
      },
      cellRenderer: SiteAccountButtonRenderer,
    },
    // more columnDefs here
  ],
};

在父 Svelte 组件中初始化网格

  <script lang="ts">
    import { Grid } from "@ag-grid-community/core";
    import { onMount } from "svelte";
    import type { SiteBalance, SiteBalancesViewModel } from "../../../typings/Payments";
    import { createGridOptions } from "./SiteBalances";
  
    export let vm: SiteBalancesViewModel;
    export let data: SiteBalance[];
  
    let gridEl: HTMLElement;
  
    onMount(async () => {
      const gridOptions = createGridOptions(vm);
      new Grid(gridEl, gridOptions);
      gridOptions.api.setRowData(data);
    });
  </script>
  
  <div style="height: 100%;" bind:this={gridEl} class="ag-theme-alpine" />

原答案

我以前没有设置过这个,但一般设置可能是这样的:

  1. 照常使用 props 创建 Svelte 组件
  2. 设置 ag-grid Cell 渲染器 2a.在
    init
    方法中,确保使用 svelte 组件的 CSS 选择器将
    this.eGui.innerHTML
    属性设置为空 div (
    <div class="svelte-widget"></div>
    ) 2b.在相同的
    init
    方法中,初始化 svelte 组件:
import SvelteWidget, { selector as SvelteWidgetSelector } from "./your-path/SvelteWidget.svelte";

class SvelteWidgetRenderer {
    init(params) {
        this.eGui = document.createElement('div');
        this.eGui.classList.add('svelte-widget');

        // initialize svelte widget with client-side component API
        new SvelteWidget({ target: this.eGui, props: { /* your props */ });
    }
}

svelte 小部件“选择器”是可选的,因为我们将 svelte 组件附加到 ag-grid DOM 元素


0
投票

我刚刚遇到了同样的问题,并在 svelte 5 项目中实现了这个问题。对于任何想知道的人来说,它最终在主要组件中看起来像这样(还有一堆额外的东西需要刷新):

...
{
      field: FIELD_NAMES.STATUS,
      headerName: DISPLAY_NAMES.status,
      editable: false,
      maxWidth: 80,
      cellRenderer: cellRendererFactory((cell, params) => {
        const props = $state({ value: params.value });

        const component = mount(CellRendererStatus, {
          target: cell.eGui,
          props
        });

        cell.refresh = (refreshParams: ICellRendererParams) => {
          props.value = refreshParams.value;
          return true;
        };

        return component;
        // optimize might have to cleanup? ... return () => { component.$destroy(); };
      })
}

不要忘记导入

ICellRendererParams
和要在单元格内渲染的组件(相应地调整你的组件),还有
mount
:

import type ICellRendererParams from "../../node_modules/ag-grid-community";
import CellRendererStatus from "./CellRendererStatus.svelte";
import { mount } from "svelte";

CellRendererStatus.svelte
是我的自定义组件,如下所示:

<script lang="ts">
  import { CheckCircleSolid, CloseCircleSolid } from "flowbite-svelte-icons";
  
  // this is the important bit
  export let value: boolean;

</script>

<div class="mt-1">
  {#if value}
    <CheckCircleSolid class="text-green-500"></CheckCircleSolid>
  {:else}
    <CloseCircleSolid class="text-red-500"></CloseCircleSolid>
  {/if}
</div>

我在单独的

AbstractCellRenderer.ts
文件中添加了 @Corrl 建议的完全相同的代码。希望这有帮助!

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