带有按钮单击的 Ag-Grid cellRender

Posted

技术标签:

【中文标题】带有按钮单击的 Ag-Grid cellRender【英文标题】:Ag-Grid cellRender with Button Click 【发布时间】:2018-11-19 13:52:49 【问题描述】:

我使用 angular 5 和 ag-grid 数据表 我无法在这里使用 cellRenderer 从单元格触发点击事件如何使用我的 ag-grid --> colDefs

this.columnDefs = [
            headerName: '#', rowDrag: true, width: 75,
            headerName: 'One', field: 'fieldName',
                cellRenderer : function(params)
                    return '<div><button (click)="drop()">Click</button></div>'
                
            
];

drop() 
    alert("BUTTON CLICKEFD")

如果我使用onClick="alert("123")" --> 它可以工作, 但我不能使用onClick="drop()" 它会抛出未定义的下降,

我也在 cellRenderer 内部尝试过 --> params = params.$scope.drop = this.drop;

如果我将 gridOptions 与 angularCompileRows : true 一起使用,则会引发错误 Cannot read property '$apply' of undefined. 我需要安装ag-grid enterprise 吗??

【问题讨论】:

我对 ag-Grid 不熟悉,但您可以尝试用箭头函数替换该函数:cellRenderer : (params) =&gt; ...。它保留了this 的值。 它不工作的伙伴... 请在将cellRenderer 属性更改为箭头函数后向我们展示您的代码。例如:headerName: 'One', field: 'fieldName', cellRenderer: (params) =&gt; return '&lt;div&gt; &lt;button (click)="drop()"&gt;Click&lt;/button&gt;&lt;/div&gt;'. cellRenderer : (params)=&gt; return '&lt;a class="showStepDef cursor_pointer" (click)="drop()" data-toggle="tooltip" data-placement="top" title="'+params.value+'"&gt;'+params.value+'&lt;/a&gt;' this.gridOptions = enableColResize: true, rowDragManaged: true, onGridReady : function(params) params.api.sizeColumnsToFit(); , rowSelection : 'single' 我试过这个它不能触发点击事件我需要在gridOptions中添加任何选项吗?? 参考***.com/questions/61493626/… 【参考方案1】:

您可以将cellRenderer 与按钮组件一起使用。 如果你想从桌面上的用户那里获取按钮的点击事件,只需将你想要的回调函数声明为cellRendererParams即可。

// app.component.ts
columnDefs = [

  headerName: 'Button Col 1',
  cellRenderer: 'buttonRenderer',
  cellRendererParams: 
    onClick: this.onBtnClick.bind(this),
    label: 'Click'
  
,
...
]

以上代码只是一小部分,请查看Stackblitz上的完整示例

【讨论】:

此评论可能对某人有所帮助。在这个问题中绑定解决方案后,点击不起作用。这是因为按钮的 z-index。我添加了 z 索引并且它起作用了。 完美答案.. 我正在寻找的那个。非常感谢【参考方案2】:

角度。 在这里,我们将按钮单元格渲染器创建为实现 ICellRendererAngularComp 接口的 Angular 组件。可以在 agInit 钩子上找到对 params 对象的访问。

// app/button-cell-renderer.component.ts
@Component(
  selector: 'btn-cell-renderer',
  template: `
    <button (click)="btnClickedHandler($event)">Click me!</button>
  `,
)
export class BtnCellRenderer implements ICellRendererAngularComp, OnDestroy 
  private params: any;
  agInit(params: any): void 
    this.params = params;
  
  btnClickedHandler() 
    this.params.clicked(this.params.value);
  
  ngOnDestroy() 
    // no need to remove the button click handler as angular does this under the hood
  

渲染器通过 gridOptions.frameworkComponents 注册到 ag-Grid。请注意,我们通过 cellRendererParams 将按钮单击处理程序动态传递给我们的渲染器 - 允许更灵活和可重用的渲染器。

// app/app.component.ts
this.columnDefs = [
    
        field: 'athlete',
        cellRenderer: 'btnCellRenderer',
        cellRendererParams: 
          clicked: function(field: any) 
            alert(`$field was clicked`);
          
        ,
        minWidth: 150,
    
    // [...]
];
this.frameworkComponents = 
    btnCellRenderer: BtnCellRenderer
;

还需要将我们的渲染器传递给我们的@NgModule 装饰器以允许依赖注入。

// app/app.modules.ts
@NgModule(
  imports: [
    BrowserModule,
    FormsModule,
    HttpClientModule,
    AgGridModule.withComponents([BtnCellRenderer]),
  ],
  declarations: [AppComponent, BtnCellRenderer],
  bootstrap: [AppComponent],
)

See demo.Learn more about Angular Cell Renderer.

原版 JavaScript。 在 init 方法中创建一个 DOM 元素,然后在 getGui 方法中返回该元素。可选的destroy hook还包括做一些清理工作(从我们的组件中移除点击监听器)。

// btn-cell-renderer.js
function BtnCellRenderer() 
BtnCellRenderer.prototype.init = function(params) 
  this.params = params;
  this.eGui = document.createElement('button');
  this.eGui.innerhtml = 'Click me!';
  this.btnClickedHandler = this.btnClickedHandler.bind(this);
  this.eGui.addEventListener('click', this.btnClickedHandler);

BtnCellRenderer.prototype.getGui = function() 
  return this.eGui;

BtnCellRenderer.prototype.destroy = function() 
  this.eGui.removeEventListener('click', this.btnClickedHandler);

BtnCellRenderer.prototype.btnClickedHandler = function(event) 
  this.params.clicked(this.params.value);

渲染器在 gridOptions.components 中注册到 ag-Grid 并用于运动员列。请注意,我们通过 cellRendererParams 将按钮单击处理程序动态传递给我们的渲染器 - 这使得渲染器更加灵活和可重用。

// main.js 
var gridOptions = 
  columnDefs: [
     
      field: 'athlete', 
      cellRenderer: 'btnCellRenderer', 
      cellRendererParams: 
        clicked: function(field) 
          alert(`$field was clicked`);
        
      ,
      minWidth: 150
    ,
  // [...]
  components: 
    btnCellRenderer: BtnCellRenderer
  
;

See demo.Learn more about javascript Cell Renderers.

反应。 在这里,我们的按钮单元格渲染器被构造为一个 React 组件。这里唯一需要注意的是,单元格参数将通过 props 在组件上可用。

// BtnCellRenderer.jsx
class BtnCellRenderer extends Component 
  constructor(props) 
    super(props);
    this.btnClickedHandler = this.btnClickedHandler.bind(this);
  
  btnClickedHandler() 
   this.props.clicked(this.props.value);
  
  render() 
    return (
      <button onClick=this.btnClickedHandler>Click Me!</button>
    )
  

渲染器通过 gridOptions.frameworkComponents 注册到 ag-Grid。按钮单击处理程序在运行时通过 cellRendererParams 传递给我们的渲染器 - 允许更灵活和可重用的渲染器。

// index.jsx
columnDefs: [
    
          field: 'athlete',
          cellRenderer: 'btnCellRenderer',
          cellRendererParams: 
            clicked: function(field) 
              alert(`$field was clicked`);
            ,
          ,
        // [...]
    
];
frameworkComponents: 
    btnCellRenderer: BtnCellRenderer,

See demo.Learn more about React Cell Renderers.

Vue.js。 在 Vue.js 中配置渲染器很简单:

// btn-cell-renderer.js
export default Vue.extend(
  template: `
        <span>
            <button @click="btnClickedHandler()">Click me!</button>
        </span>
    `,
  methods: 
    btnClickedHandler() 
      this.params.clicked(this.params.value);
    
  ,
);

与其他框架一样,渲染器通过 gridOptions.frameworkComponents 注册到 ag-Grid,并且按钮单击处理程序在运行时通过 cellRendererParams 传递给我们的渲染器 - 允许更灵活和可重用的渲染器。

// main.js
    this.columnDefs = [
      
        field: 'athlete',
        cellRenderer: 'btnCellRenderer',
        cellRendererParams: 
          clicked: function(field) 
            alert(`$field was clicked`);
          
        ,
      // [...]
    ],
    this.frameworkComponents = 
      btnCellRenderer: BtnCellRenderer
    

See demo.Learn more about Vue.js Cell Renderers.

阅读我们website 上的完整博客文章或查看我们的documentation,了解您可以使用 ag-Grid 实现的各种场景。

艾哈迈德·加迪尔 |开发者@ag-Grid

【讨论】:

此评论可能对某人有所帮助。在这个问题中绑定解决方案后,点击不起作用。这是因为按钮的 z-index。我添加了 z 索引并且它起作用了。 有什么办法可以让这个按钮组件获得一些其他数据吗?表中的一些其他字段数据,比如我想要按钮组件中的年龄字段 this.btnClickedHandler = this.btnClickedHandler.bind(this); 是一个很棒的发现,还有 this.eGui.addEventListener('click', this.btnClickedHandler); 这表明我正在尝试绑定特定的子元素,并且应该绑定 eGui 级别元素。 【参考方案3】:

为了扩展@T4professor 的答案,我将发布一些代码以在该单击按钮上也有一个动态标签。

// Author: T4professor

import  Component, OnInit, AfterContentInit  from '@angular/core';
import  ICellRendererAngularComp  from 'ag-grid-angular';

@Component(
  selector: 'app-button-renderer',
  template: `
    <button class="btnClass" type="button" (click)="onClick($event)">label</button>
    `
)

export class ButtonRendererComponent implements ICellRendererAngularComp 
    //https://stackblitz.com/edit/angular-ag-grid-button-renderer?file=src%2Fapp%2Fapp.component.ts
  params: any;
  label: string;
  getLabelFunction: any;
  btnClass: string;

  agInit(params: any): void 
    this.params = params;
    this.label = this.params.label || null;
    this.btnClass = this.params.btnClass || 'btn btn-primary';
    this.getLabelFunction = this.params.getLabelFunction;

    if(this.getLabelFunction && this.getLabelFunction instanceof Function)
    
      console.log(this.params);
      this.label = this.getLabelFunction(params.data);
    

  

  refresh(params?: any): boolean 
    return true;
  

  onClick($event) 
    if (this.params.onClick instanceof Function) 
      // put anything into params u want pass into parents component
      const params = 
        event: $event,
        rowData: this.params.node.data
        // ...something
      
      this.params.onClick(params);

    
  

然后,在带有网格的组件中执行以下操作:

columnDefs = [

    
      headerName: 'Publish',
      cellRenderer: 'buttonRenderer',
      cellRendererParams: 
        onClick: this.onRowPublishBtnClick.bind(this),        
        label: 'Publish',
        getLabelFunction: this.getLabel.bind(this),
        btnClass: 'btn btn-primary btn-sm'
      
      
]

onRowPublishBtnClick(e)     
    this.rowDataClicked = e.rowData;
  

  getLabel(rowData)
      
    console.log(rowData);
    if(rowData && rowData.hasIndicator)
      return 'Republish';
      else return 'Publish';
  

【讨论】:

【参考方案4】:

你有这个问题是因为你错误地调用了 drop() 你应该把它改成 this.drop()

一般来说,您应该使用逻辑简单的 cellRenderer 属性。对于复杂的逻辑渲染器,更方便的方法是使用 cellRendererFramework: YourCustomRendererAngularComponent。

columnDefs = [

  headerName: 'Col Name',
  cellRendererFramwork: MyAngularRendererComponent, // RendererComponent suffix it is naming convention
  cellRendererParams: 
    onClick: (params) => this.click(params);  
  
,
...
]

MyAngularRendererComponent 应该实现 AgRendererComponent。

还有在你使用 MyAngualrRendererComponent 的 Angular 模块中,不要忘记输入以下代码:

@NgModule(
 imports: [
   AgGridModule.withCompoennts([
      MyAngualrRendererComponent 
   ])
 ]
)

【讨论】:

以上是关于带有按钮单击的 Ag-Grid cellRender的主要内容,如果未能解决你的问题,请参考以下文章

Ag-grid 中的模态

Ag-grid:在侧边栏面板外部以角度单击时隐藏列侧边栏

对列标题上的多个列进行排序,单击 ag-grid

Angular 6 ag-grid 单元格渲染器单击功能

如何将菜单按钮添加到 ag-Grid 行?

AngularJs 在 UI 路由器状态视图中向 ag-grid 单元格添加按钮