【问题标题】:Ag-Grid cellRender with Button Click带有按钮单击的 Ag-Grid cellRender
【发布时间】: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中添加任何选项吗??

标签: javascript typescript angular5 ag-grid ag-grid-ng2


【解决方案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 
       ])
     ]
    })
    

    【讨论】:

      猜你喜欢
      • 2019-10-07
      • 2019-08-06
      • 1970-01-01
      • 2021-10-28
      • 2021-03-31
      • 2019-10-07
      • 2021-07-16
      • 2018-10-10
      • 2018-08-30
      相关资源
      最近更新 更多