无法禁用ag-grid中的按钮

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

我想使用 ag-grid 中另一列中按钮的单击事件禁用列中的按钮。

我已经使用通用服务来禁用它,但它禁用了该列中的所有按钮,我还尝试更新参数对象(rowData)中的该列字段,但没有工作。

这是 stackbltiz

上的示例

编辑:添加源代码

app.component.html

<h1>Hello World</h1>

<ag-grid-angular
  style="width: 500px; height: 350px;"
  class="ag-theme-alpine"
  [rowData]="rowData"
  [columnDefs]="columnDefs"
>
</ag-grid-angular>

app.component.ts

import { Component } from '@angular/core';
import { ColDef } from 'ag-grid-community';
import { ButtonRendererComponent } from './button-renderer/button-renderer.component';
@Component({
  selector: 'my-app',
  styleUrls: ['./app.component.css'],
  templateUrl: './app.component.html',
})
export class AppComponent {
  columnDefs: ColDef[] = [
    {
      field: 'make',
      headerName: 'Button1',
      cellRenderer: ButtonRendererComponent,
      cellRendererParams: {
        comp: 'label1',
      },
    },
    {
      field: 'model',
      headerName: 'Button1',
      cellRenderer: ButtonRendererComponent,
      cellRendererParams: {
        comp: 'label2',
      },
    },
    { field: 'price' },
  ];

  rowData = [
    {
      make: 'Toyota',
      model: 'Celica',
      price: 35000,
      button1: true,
      button2: false,
    },
    {
      make: 'Ford',
      model: 'Mondeo',
      price: 32000,
      button1: true, //fetched from DB
      button2: false, //fetched from DB
    },
    {
      make: 'Porsche',
      model: 'Boxster',
      price: 72000,
      button1: true, //fetched from DB
      button2: false, //fetched from DB
    },
  ];
}

按钮渲染器.component.html

<button
  *ngIf="params['comp'] == 'label1'"
  mat-flat-button
  color="primary"
  (click)="clickButton1()"
  [disabled]="isButton1Disabled"
>
  Button1
</button>
<button
  *ngIf="params['comp'] == 'label2'"
  mat-flat-button
  color="primary"
  (click)="clickButton2()"
  [disabled]="comSvc.isButtonDisabled"
>
  Button2
</button>

按钮渲染器.component.ts

import { Component, OnInit } from '@angular/core';
import { ICellRendererAngularComp } from 'ag-grid-angular';
import { ICellRendererParams } from 'ag-grid-community';
import { CommonService } from '../common.service';

@Component({
  selector: 'app-button-renderer',
  templateUrl: './button-renderer.component.html',
  styleUrls: ['./button-renderer.component.css'],
})
export class ButtonRendererComponent implements ICellRendererAngularComp {
  params: any;
  isButton1Disabled: boolean = false;
  isButton2Disabled: boolean = true;
  agInit(params: ICellRendererParams): void {
    this.params = params;
  }

  // gets called whenever the cell refreshes
  refresh(params: ICellRendererParams): boolean {
    // set value into cell again
    return true;
  }
  constructor(public comSvc: CommonService) {}

  ngOnInit() {}
  clickButton1() {
    console.log('Button 1 is clicked');
    // this.isButton2Disabled = true;
    // this.params.button2 = true;
    this.comSvc.isButtonDisabled = true;
    //DB update call
  }
  clickButton2() {
    console.log('Button 2 is clicked');
    //DB update call
  }
}

套餐:

Angular: 16.2.0 
ag-grid-angular: 30.2.0
angular button ag-grid ag-grid-angular
1个回答
0
投票

使用当前代码禁用每个按钮是正常的,因为该服务对于每个组件都是通用的,并且按钮只有一种状态。这意味着所有按钮都具有相同的禁用状态。

解决方案 1:使用保持所有行禁用状态的服务

解决方案是保留您的服务并拥有 id 行和禁用状态的映射

单元格渲染器组件 html:

<button *ngIf="params['comp'] == 'label1'" mat-flat-button color="primary" (click)="clickButton1()">
  Button1
</button>
<button *ngIf="params['comp'] == 'label2'" mat-flat-button color="primary" (click)="clickButton2()" [disabled]="comSvc.isDisabled(this.params.rowIndex)">
  Button2
</button>

单元格渲染器组件 ts:

import { Component, OnInit } from '@angular/core';
import { ICellRendererAngularComp } from 'ag-grid-angular';
import { ICellRendererParams } from 'ag-grid-community';
import { CommonService } from '../common.service';

@Component({
  selector: 'app-button-renderer',
  templateUrl: './button-renderer.component.html',
})
export class ButtonRendererComponent implements ICellRendererAngularComp {
  params: any;

  agInit(params: ICellRendererParams): void {
    this.params = params;
  }

  // gets called whenever the cell refreshes
  refresh(params: ICellRendererParams): boolean {
    // set value into cell again
    return true;
  }

  constructor(public comSvc: CommonService) {}

  clickButton1() {
    console.log(`Button 1 is clicked on row index${this.params.rowIndex}`);
    this.comSvc.disableButtonOnRow(this.params.rowIndex);
    //DB update call
  }
  clickButton2() {
    console.log('Button 2 is clicked');
    //DB update call
  }
}

服务:

import { Injectable } from '@angular/core';

@Injectable()
export class CommonService {
  private disabledButtonByRow = new Map<number, boolean>();

  public disableButtonOnRow(rowId: number): void {
    this.disabledButtonByRow.set(rowId, true);
  }

  public isDisabled(rowId: number): boolean {
    console.log('is disabled is called!' + rowId);
    return !!(
      this.disabledButtonByRow.has(rowId) && this.disabledButtonByRow.get(rowId)
    );
  }
}

解决方案 2:将两个按钮放在同一个单元格渲染器中

为什么一个单元格渲染器组件中有 2 个带有 if 的按钮,而它们之间没有共享逻辑并且只显示一个。 当您在一个单元格中显示两个按钮时,事情会变得更容易,因为您可以共享逻辑。

单元格渲染器组件 html:

<button mat-flat-button color="primary" (click)="clickButton1()">
  Button1
</button>
<button mat-flat-button color="primary" (click)="clickButton2()" [disabled]="button2DisabledState">
  Button2
</button>

单元格渲染器组件 ts:

import { Component } from '@angular/core';
import { ICellRendererAngularComp } from 'ag-grid-angular';
import { ICellRendererParams } from 'ag-grid-community';

@Component({
  selector: 'app-button-renderer',
  templateUrl: './button-renderer.component.html',
})
export class ButtonRendererComponent implements ICellRendererAngularComp {
  button2DisabledState= false;

  agInit(): void {
  }

  // gets called whenever the cell refreshes
  refresh(params: ICellRendererParams): boolean {
    // set value into cell again
    return false;
  }

  clickButton1() {
    this.button2DisabledState= true;
    //DB update call
  }
  clickButton2() {
    console.log('Button 2 is clicked');
    //DB update call
  }
}

表格组件ts:

import { Component } from '@angular/core';
import { ColDef } from 'ag-grid-community';
import { ButtonRendererComponent } from './button-renderer/button-renderer.component';
@Component({
  selector: 'my-app',
  styleUrls: ['./app.component.css'],
  templateUrl: './app.component.html',
})
export class AppComponent {
  columnDefs: ColDef[] = [
    {
      field: 'make',
      headerName: 'Button1 & 2',
      cellRenderer: ButtonRendererComponent,
      flex:2
    },
    { field: 'price',
      flex: 1 
    },
  ];

  rowData = [
    {
      make: 'Toyota',
      model: 'Celica',
      price: 35000,
      button1: true,
      button2: false,
    },
    {
      make: 'Ford',
      model: 'Mondeo',
      price: 32000,
      button1: true, //fetched from DB
      button2: false, //fetched from DB
    },
    {
      make: 'Porsche',
      model: 'Boxster',
      price: 72000,
      button1: true, //fetched from DB
      button2: false, //fetched from DB
    },
  ];
}

解决方案 3:更新行数据以刷新单元格渲染器

单元格渲染器组件 html:

<button
  mat-flat-button
  color="primary"
  (click)="params.actionOnClick()"
  [disabled]="params.value"
>
  {{params.buttonName}}
</button>

单元格渲染器组件 ts:

import { Component, OnInit } from '@angular/core';
import { ICellRendererAngularComp } from 'ag-grid-angular';
import { ICellRendererParams } from 'ag-grid-community';

@Component({
  selector: 'app-button-renderer',
  templateUrl: './button-renderer.component.html',
})
export class ButtonRendererComponent implements ICellRendererAngularComp {
  params: any;

  agInit(params: ICellRendererParams): void {
    this.params = params;
  }

  // gets called whenever the cell refreshes
  refresh(params: ICellRendererParams): boolean {
    // set value into cell again
    return false;
  }
}

表格组件ts:

import { Component } from '@angular/core';
import { ColDef } from 'ag-grid-community';
import { ButtonRendererComponent } from './button-renderer/button-renderer.component';
@Component({
  selector: 'my-app',
  styleUrls: ['./app.component.css'],
  templateUrl: './app.component.html',
})
export class AppComponent {
  columnDefs: ColDef[] = [
    {
      field: 'button1',
      headerName: 'Button1',
      cellRenderer: ButtonRendererComponent,
      cellRendererParams: (params: any) => ({
        buttonName: 'Button 1',
        actionOnClick: () => {
          console.log(`Button 1 is clicked on row index${params.rowIndex}`);
          this.rowData[params.rowIndex].button2 = true;
          // force aggrid to detect changes in row Data
          this.rowData = [...this.rowData];
        },
      }),
    },
    {
      field: 'button2',
      headerName: 'Button2',
      cellRenderer: ButtonRendererComponent,
      cellRendererParams: {
        buttonName: 'Button 2',
        actionOnClick: () => {
          console.log('Button 2 is clicked');
          //DB update call
        },
      },
    },
    { field: 'price' },
  ];

  rowData = [
    {
      make: 'Toyota',
      model: 'Celica',
      price: 35000,
      button1: false,
      button2: false,
    },
    {
      make: 'Ford',
      model: 'Mondeo',
      price: 32000,
      button1: false, //fetched from DB
      button2: false, //fetched from DB
    },
    {
      make: 'Porsche',
      model: 'Boxster',
      price: 72000,
      button1: true, //fetched from DB
      button2: false, //fetched from DB
    },
  ];
}

这里重要的部分是

this.rowData = [...this.rowData];
,它可以帮助aggrid检测rowData中的变化

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