Javascript Ag-Grid cellRender with Button Click

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/50778659/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 04:40:49  来源:igfitidea点击:

Ag-Grid cellRender with Button Click

javascripttypescriptangular5ag-gridag-grid-ng2

提问by YuvaMac

I am using an angular 5 with ag-grid data table i cant able to trigger a click event from cell using cellRenderer here how am using my ag-grid --> colDefs

我正在使用带有 ag-grid 数据表的 angular 5 我无法在此处使用 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")
}

if am using onClick="alert("123")"--> it works, but i cant able to use onClick="drop()"it throws drop of undefined,

如果正在使用onClick="alert("123")"--> 它有效,但我无法使用onClick="drop()"它会抛出未定义的一滴,

i tried this too inside of cellRenderer --> params = params.$scope.drop = this.drop;

我也在 cellRenderer --> params = 里面试过这个 params.$scope.drop = this.drop;

if am using gridOptions with angularCompileRows : trueit throws an error Cannot read property '$apply' of undefined.Do i need to install ag-grid enterprise??

如果使用 gridOptionsangularCompileRows : true会引发错误Cannot read property '$apply' of undefined.我需要安装ag-grid enterprise吗??

回答by T4professor

You can use cellRendererwith a button component. If you want to get the click event on the button from the user on the table, just declare the callback function you want to cellRendererParams.

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

// app.component.ts
columnDefs = [
{
  headerName: 'Button Col 1',
  cellRenderer: 'buttonRenderer',
  cellRendererParams: {
    onClick: this.onBtnClick.bind(this),
    label: 'Click'
  }
},
...
]

The above code is just a small part, check out full exampleon Stackblitz

上面的代码只是一小部分,检查出完整的例子Stackblitz

回答by ahmedg94

Angular.
Here we create the button cell renderer as an Angular component that implements the ICellRendererAngularComp interface. Access to the params object can be found on the agInit hook.


在这里,我们将按钮单元渲染器创建为实现 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
  }
}

The renderer is registered to ag-Grid via gridOptions.frameworkComponents. Note that we're passing the button click handler dynamically to our renderer via cellRendererParams - allowing for a more flexible and reusable renderer.

渲染器通过 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
    };

It is also necessary to pass our renderer to our @NgModule decorator to allow for dependency injection.

还需要将我们的渲染器传递给我们的 @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.

见演示
了解有关 Angular Cell Renderer 的更多信息

Vanilla JavaScript.
A DOM element is created in the init method, which is then returned in the getGui method. The optional destroy hook has also included to do some cleanup (removing the click listener from our component).

香草 JavaScript
在 init 方法中创建了一个 DOM 元素,然后在 getGui 方法中返回。可选的 destroy 钩子还包括进行一些清理(从我们的组件中删除点击侦听器)。

// 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);
}

The renderer is registered to ag-Grid in gridOptions.components and is used on the athlete column. Note that we're passing the button click handler dynamically to our renderer via cellRendererParams - this makes for a more flexible and reusable renderer.

渲染器在 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.

见演示
了解有关 JavaScript 单元格渲染器的更多信息

React.
Here our button cell renderer is constructed as a React component. The only thing to take note of here is that cell params will be available on the component via props.

反应
这里我们的按钮单元渲染器被构造为一个 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>
    )
  }
}

The renderer is registered to ag-Grid via gridOptions.frameworkComponents. The button click handler is passed to our renderer at run time via cellRendererParams - allowing for a more flexible and reusable renderer.

渲染器通过 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.

见演示
了解有关 React Cell 渲染器的更多信息

Vue.js.
Configuring the renderer in Vue.js is simple:

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);
    }
  },
});

As with the other frameworks, the renderer is registered to ag-Grid via gridOptions.frameworkComponents and the button click handler is passed to our renderer at run time via cellRendererParams - allowing for a more flexible and reusable renderer.

与其他框架一样,渲染器通过 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.

见演示
了解有关 Vue.js 单元格渲染器的更多信息

Read the full blog post on our websiteor check out our documentationfor a great variety of scenarios you can implement with ag-Grid.

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

Ahmed Gadir | Developer @ ag-Grid

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

回答by Dragos Durlut

To expand on the answer from @T4professor, I will post some code to also have a dynamic label on that Click button.

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

// 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);

    }
  }
}

Then, in the component with the grid you do the following:

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

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';
  }

回答by CREZi

You have this issue because you invoke drop() incorrectly you should change it to this.drop()

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

In general you should use cellRenderer property with simple logic. More convenient way for complex logic renderer you should use cellRendererFramework: YourCustomRendererAngularComponent.

通常,您应该使用具有简单逻辑的 cellRenderer 属性。对于复杂的逻辑渲染器,您应该使用 cellRendererFramework:YourCustomRendererAngularComponent 更方便的方法。

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

MyAngularRendererComponent should implements AgRendererComponent.

MyAngularRendererComponent 应该实现 AgRendererComponent。

Also in angular module where you use MyAngualrRendererComponent don`t forget put this code:

同样在使用 MyAngualrRendererComponent 的 angular 模块中,不要忘记放置以下代码:

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