【问题标题】:Dynamically update non-data property in custom AG Grid cell renderer在自定义 AG Grid 单元格渲染器中动态更新非数据属性
【发布时间】:2022-11-05 19:59:26
【问题描述】:

我有一个网格,我想在每一行的列中显示一个编辑器按钮,并在网格外显示一个新的项目创建者按钮。

业务要求是在按下创建或编辑按钮时,所有按钮都必须进入禁用状态。

我为编辑按钮创建了一个自定义单元格渲染器,其中包含一个控制禁用状态的属性,但我不知道如何从网格上下文外部更新该属性。

我能够实现所需行为的唯一方法是将isDisabled 状态作为函数传递给单元格渲染器,包装外部值,并利用 Angular 在模板中处理表达式的方式。在这种情况下,Angular 不知道如何处理不确定的值,只是将isDisabled() 函数调用为无穷大,当我更改外部包装的值时,单元格最终也会更新。

I've created a sample for convenience

@Component({
  selector: 'app-ag-grid-edit-renderer',
  template: `
  <button
  class="ag-edit-button"
  (click)="onClick()"
  [disabled]="isDisabled()"
>
  Edit
</button>`,
})
export class AgGridEditRendererComponent implements AgRendererComponent {
  private params: any;

  isDisabled = () => false; // this is a bad practice because Angualr needs to constantly evaluate its value

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

  refresh(): boolean {
    return false;
  }

  onClick() {
    this.params.clicked(this.params.data);
  }
}

我使用以下设置网格:

export class AppComponent {
  isDisabled = false;
  currentVal: number | string = 0;

  columnDefs = [ 
    { field: "id", 
      cellRendererFramework: AgGridEditRendererComponent, 
      cellRendererParams: { 
        isDisabled: () => this.isDisabled,
        clicked: (params) => this.openEdit(params.id)
      }
    }, 
    { field: "make" }, { field: "model" }, { field: "price" }
  ];

  rowData = [
    { id: 1, make: "Toyota", model: "Celica", price: 35000 },
    { id: 2, make: "Ford", model: "Mondeo", price: 32000 },
    { id: 3, make: "Porsche", model: "Boxter", price: 72000 }
  ];

  openNew() {
    this.isDisabled = true;
    this.currentVal = 'new item';
  }

  openEdit(val: any) {
    this.isDisabled = true;
    this.currentVal = val;
  }

  closeDialog() {
    this.isDisabled = false;
  }
}

我尝试了各种方法来触发单元格刷新或通过Grid API 刷新行,但似乎没有任何效果。

我也考虑过使用Observable 或类似的,但这似乎有点过头了。

这是一个通用的单元格渲染器,所以我需要一个在大多数情况下都可以工作的简单解决方案,因此例如扩展(污染)具有特殊临时属性的数据模型实际上是不可行的。

【问题讨论】:

    标签: angular typescript ag-grid-angular


    【解决方案1】:

    【讨论】:

      【解决方案2】:

      您是否尝试过强制刷新它?

      您面临的问题是,如果单元格的值没有更改,则 ag 网格不会刷新,这就是您需要使用force: true 的原因。根据 ag grid 的版本,这可能会以另一种方式完成,但想法是相同的,尽管值没有改变,但您需要告诉 ag-grid 刷新单元格。

          gridOptions.api.refreshCells({
            force: true,
            columns: ['id'], // colId of the column you want to refresh
          });
      
        columnDefs = [ 
          { field: "id",
            colId: 'id' // add this
            cellRendererFramework: AgGridEditRendererComponent, 
            cellRendererParams: { 
              isDisabled: () => this.isDisabled,
              clicked: (params) => this.openEdit(params.id)
            }
          }, 
          { field: "make" }, { field: "model" }, { field: "price" }
        ];
      

      此外,您需要从刷新回调中返回 true

      export class AgGridEditRendererComponent implements AgRendererComponent {
        private params: any;
      
        isDisabled = () => false; // this is a bad practice because Angualr needs to constantly evaluate its value
      
        constructor(
          private cdr: ChangeDetectorRef,
        ) {}
      
        agInit(params: any): void {
          this.init(params);
        }
      
        // move initialization login to init and execute it both on refresh and agInit
        refresh(params: any): boolean {
          this.init(params)
          return true;
        }
      
        onClick() {
          this.params.clicked(this.params.data);
        }
      
        private init(params: any) {
          this.params = params;
          this.isDisabled = params.isDisabled;
          this.cdr.markForCheck();
        }
      }
      

      为什么认为模板中的函数是一种不好的做法? 你的函数只返回布尔值,它没有任何计算逻辑,所以你很好。 当您在该函数中有某种循环或繁重的逻辑时,可能会出现问题。但这也可以通过使用onPush 更改检测来减少更改检测检查的数量来解决。

      【讨论】:

        猜你喜欢
        • 2017-10-25
        • 2020-03-22
        • 1970-01-01
        • 2019-01-13
        • 2021-09-13
        • 2020-06-11
        • 2018-10-13
        • 2018-02-13
        • 2019-09-06
        相关资源
        最近更新 更多