You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ag-grid如何在plain JS渲染器中使用Angular Material组件

问题原因

你直接通过innerHTML写入<mat-radio-button>标签的方式无法正常渲染,是因为Angular Material组件属于Angular框架组件,必须经过Angular的编译流程才能解析依赖、绑定属性、渲染为可用的DOM节点,纯JS插入的原生HTML没有经过编译步骤,只会作为普通自定义标签原样显示。


方案1:手动动态编译Angular组件(保留组件完整能力)

这种方式可以保留Material组件的全部原生能力,性能优于AgGrid官方的框架渲染器,因为你可以自主控制编译和变更检测时机,减少多余的框架开销。

前置配置

确保你所在的Angular模块已经导入了MatRadioModule,如果你使用的是Angular 13以下版本,还需要将MatRadioButton加入模块的entryComponents数组。

代码实现

首先在定义AgGrid配置的Angular组件中传入编译所需的依赖:

import { Component, Injector, ComponentFactoryResolver } from '@angular/core';
// 其他AgGrid、Material相关导入

@Component({
  // 你的组件元数据配置
})
export class YourGridComponent {
  constructor(
    private injector: Injector,
    private componentFactoryResolver: ComponentFactoryResolver
  ) {}

  columnDefs = [
    {
      headerName: '选项',
      field: 'option',
      cellRenderer: plainJsRadioRenderer,
      // 将Angular编译依赖通过参数传给渲染器
      cellRendererParams: {
        injector: this.injector,
        componentFactoryResolver: this.componentFactoryResolver
      }
    }
  ];
}

修改你的渲染器类:

class plainJsRadioRenderer {
  eGui: any;
  radioCompRef: any;

  init(params) {
    this.eGui = document.createElement('div');
    const { injector, componentFactoryResolver } = params;
    // 创建MatRadioButton组件工厂
    const radioFactory = componentFactoryResolver.resolveComponentFactory(MatRadioButton);
    // 基于当前容器创建组件实例
    this.radioCompRef = radioFactory.create(injector, [], this.eGui);
    // 自定义组件属性
    this.radioCompRef.instance.label = 'Option 1';
    this.radioCompRef.instance.value = params.value;
    // 手动触发变更检测完成渲染
    this.radioCompRef.changeDetectorRef.detectChanges();

    // 可选:绑定组件事件
    this.radioCompRef.instance.change.subscribe((event) => {
      // 处理单选选中逻辑
    })
  }

  getGui() {
    return this.eGui;
  }

  refresh(params) {
    // 数据更新时手动更新组件属性
    this.radioCompRef.instance.checked = params.value === 'targetValue';
    this.radioCompRef.changeDetectorRef.detectChanges();
    return true;
  }

  // 组件销毁时手动销毁动态创建的实例,避免内存泄漏
  destroy() {
    if (this.radioCompRef) this.radioCompRef.destroy();
  }
}

如果你使用Angular 13+版本,ComponentFactoryResolver已废弃,可以直接用createComponent方法实现,代码更简洁:

// init方法修改为
init(params) {
  this.eGui = document.createElement('div');
  const { injector, environmentInjector } = params;
  this.radioCompRef = createComponent(MatRadioButton, {
    environmentInjector: environmentInjector,
    hostElement: this.eGui
  });
  // 后续属性赋值、变更检测逻辑不变
}

方案2:直接使用Material编译后的原生结构(性能最优)

如果你的需求比较简单,不需要用到Material组件的复杂绑定能力,可以直接拼接Material组件编译后的原生HTML+样式类,完全跳过框架编译步骤,性能是所有方案中最好的,仅需要自己手动处理交互逻辑:

class plainJsRadioRenderer {
  eGui: any;
  radioInput: HTMLInputElement;

  init(params) {
    this.eGui = document.createElement('div');
    // 直接使用Material编译后的DOM结构和样式类
    this.eGui.innerHTML = `
      <div class="mat-radio-button mat-accent">
        <label class="mat-radio-label">
          <span class="mat-radio-container">
            <span class="mat-radio-outer-circle"></span>
            <span class="mat-radio-inner-circle"></span>
            <input type="radio" class="mat-radio-input" name="radio-group" value="${params.value}">
          </span>
          <span class="mat-radio-label-content">Option 1</span>
        </label>
      </div>
    `;
    this.radioInput = this.eGui.querySelector('input');
    // 手动绑定交互事件
    this.radioInput.addEventListener('change', (e) => {
      // 处理选中状态切换逻辑
    })
  }

  getGui() {
    return this.eGui;
  }

  refresh(params) {
    this.radioInput.checked = params.value === 'targetValue';
    return true;
  }
}

内容的提问来源于stack exchange,提问作者kk-at-cbx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.08 15:36:03