在ag-grid中进行单元格编辑时,下拉列表未正确绑定

时间:2019-06-18 17:42:14

标签: angular ag-grid

我正在我的angular 7应用程序中实现ag-grid的单元格编辑功能。我需要显示其中一个单元格的下拉值。我在cellEditorParams中设置下拉列表的值。我可以看到值已经绑定,但没有显示下拉列表。有人可以告诉我这里是什么问题

   cellEditorParams: {
      values: this.DocumentUploadDetails.DocumentTypes,
      cellRenderer: (params) => params.value.Name
    }

我怀疑问题在于此行     cellRenderer:(参数)=> params.value.Name

我实现了以下用于单元格编辑的事件

     onCellClicked($event){
    // check whether the current row is already opened in edit or not
    if(this.editingRowIndex != $event.rowIndex) {
      console.log($event);
      $event.api.startEditingCell({
        rowIndex: $event.rowIndex,
        colKey: $event.column.colId
      });
      this.editingRowIndex = $event.rowIndex;
    }
  }

JSON

DocumentTypes is basically collection of Id and Name properties

[{"Id":4,"Name":"DD Questionnaires / Materials"},{"Id":6,"Name":"Constitutional Documents"},{"Id":7,"Name":"Regulation / References"},{"Id":8,"Name":"Email Correspondence"},{"Id":10,"Name":"Manager Letters"},{"Id":13,"Name":"Office Maps"},{"Id":14,"Name":"Quantitative"},{"Id":1,"Name":"Fund"},{"Id":20,"Name":"Other"},{"Id":21,"Name":"Fund DD Visit"},{"Id":23,"Name":"Investment Proposal"},{"Id":22,"Name":"Research Note"},{"Id":102,"Name":"Fund Organizational Document - Articles of Association"},{"Id":104,"Name":"Form ADV - Part 1"},{"Id":105,"Name":"Due Diligence Questionnaire"},{"Id":106,"Name":"Financial Statements"},{"Id":107,"Name":"Fund Organizational Document - Limited Partnership Agreement"},{"Id":108,"Name":"Investment Management Agreement"},{"Id":109,"Name":"Marketing Presentation"},{"Id":110,"Name":"Third Party Research - Morningstar Report"},{"Id":111,"Name":"Newsletter"},{"Id":112,"Name":"Offering Circular"},{"Id":113,"Name":"Side Letter"},{"Id":114,"Name":"Risk Exposure"},{"Id":115,"Name":"Redemption Form"},{"Id":116,"Name":"Offering Circular - Supplement"},{"Id":117,"Name":"Subscription Form - Additional Subscription"},{"Id":118,"Name":"Subscription Form - Non US Investor"},{"Id":119,"Name":"Subscription Form - US Tax Exempt"},{"Id":120,"Name":"Subscription Form - US Investor"},{"Id":123,"Name":"Termination Letter"},{"Id":125,"Name":"Corporate Communications"},{"Id":126,"Name":"Articles - News"},{"Id":127,"Name":"Detailed AUM"},{"Id":128,"Name":"Cube Risk Document"},{"Id":132,"Name":"Valuation Memo"},{"Id":133,"Name":"SEC 13F"},{"Id":134,"Name":"NAV Statements"},{"Id":135,"Name":"Corporate Action"},{"Id":137,"Name":"Form ADV - Part 2"},{"Id":138,"Name":"Third Party Research - Other"},{"Id":141,"Name":"Factor Analysis"},{"Id":142,"Name":"Peer Group"},{"Id":143,"Name":"Quant Report"},{"Id":144,"Name":"ODD Report"},{"Id":145,"Name":"Activity Note"},{"Id":146,"Name":"Certificates of Formation"},{"Id":147,"Name":"Financial Statements Audit"},{"Id":148,"Name":"Articles of Association"},{"Id":149,"Name":"Limited Partnership Agreement"},{"Id":150,"Name":"Subscription Documents"},{"Id":151,"Name":"Advisory Agreement"},{"Id":153,"Name":"1.1+Call%2fMeeting+Notes"},{"Id":100,"Name":"White Papers"},{"Id":101,"Name":"Summary of Terms"},{"Id":103,"Name":"Conference Presentation"},{"Id":154,"Name":"2.1+Monthly+Reports"},{"Id":155,"Name":"2.2%2bQtrly%252fSemi-Ann%252fAnnual%2bRpts"},{"Id":156,"Name":"2.3+Performance+%2f+Estimates"},{"Id":157,"Name":"3.1%2bPitchbook%252fPresentation%252fDDQ"},{"Id":158,"Name":"3rd Party Research - Mgr/Fund"},{"Id":159,"Name":"3rd Party Research - Position"},{"Id":160,"Name":"Account Statements"},{"Id":161,"Name":"Agreed-Upon Procedure (AUP) Reports"},{"Id":162,"Name":"Business Continuity Plans (BCP)"},{"Id":163,"Name":"Call/Meeting Notes"},{"Id":164,"Name":"Capital Call Letters"},{"Id":165,"Name":"Code of Ethics"},{"Id":166,"Name":"Compliance Manual"},{"Id":167,"Name":"Confidentiality Agreements"},{"Id":168,"Name":"Counterparty Exposure Report"},{"Id":169,"Name":"Distribution / Redemption Notices"},{"Id":170,"Name":"E-Mail Exchange (mgr items that don't belong to other sub-cats)"},{"Id":171,"Name":"EnTrust Allocation Memo"},{"Id":172,"Name":"EnTrust DDQ"},{"Id":173,"Name":"EnTrust Exposure Template"},{"Id":174,"Name":"EnTrust Exposure Templates"},{"Id":175,"Name":"EnTrust Expsoure Template"},{"Id":176,"Name":"EnTrust Investment Memos"},{"Id":177,"Name":"EnTrust ODD Checklist"},{"Id":178,"Name":"EnTrust ODD Meeting Notes"},{"Id":179,"Name":"EnTrust Operational Dashboard"},{"Id":180,"Name":"Exposure / Attribution"},{"Id":181,"Name":"FAS 157 Reporting"},{"Id":182,"Name":"Firm AUM History"},{"Id":183,"Name":"Firm SAS 70 (Type I or II) Reports"},{"Id":184,"Name":"Firm/Fund AUM History"},{"Id":185,"Name":"Flash Notes"},{"Id":186,"Name":"Form ADV Part I"},{"Id":187,"Name":"Form ADV Part II"},{"Id":188,"Name":"Fund DDQ"},{"Id":189,"Name":"Fund Personnel Biographies"},{"Id":190,"Name":"Fund Personnel Changes"},{"Id":191,"Name":"Fund Pitch Book / Marketing Deck"},{"Id":192,"Name":"Fund Pitch Book / Marketing Decks"},{"Id":193,"Name":"Fund Prospectus"},{"Id":194,"Name":"Fund Structure Chart"},{"Id":195,"Name":"Historical Exposure / Historical Attribution"},{"Id":196,"Name":"Investment Manager Agreement (IMA)"},{"Id":197,"Name":"Investor Type Breakout"},{"Id":198,"Name":"Key Personnel Background Checks"},{"Id":199,"Name":"LPA / LLC Agreement"},{"Id":200,"Name":"Limited Partnership Agreement (LPA)"},{"Id":201,"Name":"Liquidity Breakout"},{"Id":202,"Name":"Mail Correspondence"},{"Id":203,"Name":"Manager DDQ"},{"Id":204,"Name":"Manager Reporting"},{"Id":205,"Name":"Monthly Flash Call"},{"Id":206,"Name":"Monthly Reports"},{"Id":207,"Name":"Monthly Reports (Investor Letter, Exposure, Allocation)"},{"Id":208,"Name":"Most Favored Nations (MFN) / Side Letters"},{"Id":209,"Name":"OPERA"},{"Id":210,"Name":"Opportunistic Investments"},{"Id":211,"Name":"Organizational Chart"},{"Id":212,"Name":"Other Firm Policy"},{"Id":213,"Name":"Other Firm Reporting"},{"Id":214,"Name":"Other Operational Reporting"},{"Id":215,"Name":"Performance"},{"Id":216,"Name":"Performance / Estimates"},{"Id":217,"Name":"Personal Trading Policy"},{"Id":218,"Name":"Pitchbook, Presentation, Manager/Fund DDQ"},{"Id":219,"Name":"Private Placement Memorandum (PPM)"},{"Id":220,"Name":"Proxy Voting Policy"},{"Id":221,"Name":"Quarterly, Semi-Annual, Annual Reports"},{"Id":222,"Name":"Redemption Documents"},{"Id":223,"Name":"Research Clippings : Manager Level"},{"Id":224,"Name":"Research Clippings : Position Level"},{"Id":225,"Name":"Service Provider Agreements / Descriptions of Service"},{"Id":226,"Name":"Service Provider Confirmations / DDQs"},{"Id":227,"Name":"Service Provider SAS 70 (Type I or II) Reports"},{"Id":228,"Name":"Temp"},{"Id":229,"Name":"Trade Error Policy"},{"Id":230,"Name":"Trade Flow / Operational Processes"},{"Id":231,"Name":"Valuation / Pricing Review Support"},{"Id":232,"Name":"Valuation / Pricing Source Breakout"},{"Id":233,"Name":"Valuation Policy"},{"Id":234,"Name":"zz_(DD-ODD)"},{"Id":235,"Name":"zz_(Fund Info)"},{"Id":236,"Name":"zz_(Governing Docs)"},{"Id":237,"Name":"zz_(Other)"},{"Id":238,"Name":"Daily/Weekly/Monthly Letters/Reports"},{"Id":239,"Name":"Quarterly Letters/Reports"},{"Id":240,"Name":"Annual Letters/Reports"},{"Id":242,"Name":"Meeting Notes"},{"Id":243,"Name":"Weekly Performance"},{"Id":244,"Name":"Mid-Month Performance"},{"Id":245,"Name":"Monthly Performance"},{"Id":246,"Name":"Quarterly Flash Bullets"},{"Id":247,"Name":"Activity Attachment"},{"Id":249,"Name":"Trade Slide"}]

HTML

<div class="card" *ngIf="DocumentUploadDetails && DocumentUploadDetails.DocumentEntities" style="margin-top: 10px" >
    <div class="card-body" style="width:100%; text-align: left;">
        <div style="overflow-x: hidden; overflow-y: hidden; ">
            <div class="form-group row">
                <div class="panel panel-default col-md-12  ">
                    <div class="panel-body">
                        <div id="grid-wrapper" [style.height.px]="GridHeight()" [style.width.%]="100"
                            style="float: left;">
                            <ag-grid-angular #agGrid class="ag-theme-balham" [gridOptions]="GridOptions"
                                style="width: 100%; height: 100%" [columnDefs]="ColumnDefs" rowHeight="30"
                                [rowData]="DocumentUploadDetails.DocumentEntities"
                                [editType]="editType"
                                (cellClicked)="onCellClicked($event)"
                                headerHeight="30" rowSelection="single">
                            </ag-grid-angular>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

组件

import { Component, Injectable, NgZone, ViewEncapsulation, ViewChild, Input } from '@angular/core'
import { OnInit } from '@angular/core'
import { Comparator } from '../utilities/comparator';
import { GridOptions, GridApi } from 'ag-grid-community';
import { DocumentUploadService } from '../services/documentUpload.service';
import { NotifyService } from '../utilities/notify.service';
import { number } from '@amcharts/amcharts4/core';

@Component({
    selector: 'mgr-document-upload',
    templateUrl: './documentUpload.component.html'
})

export class DocumentUploadComponent implements OnInit {
    Files: Array<File>;
    ColumnDefs: Array<any> = new Array<any>();
    private Comparator: Comparator;
    private Error: string;
    private gridApi: GridApi;
    public GridOptions: GridOptions;
    private editClicked;
    private editingRowIndex;
    private editType;
    ngZone: any;
    windowHeight: any;
    offset: number;
    Loading: boolean;
    public DocumentUploadDetails: any;
    public params: any;
    @Input() ManagerStrategyId = 5508;
    MgrStrategyId = 5508;


    ngOnInit() {
        this.setGridOptions();
        this.getDocumentUploadDetails();
    }


    constructor(private comparator: Comparator, private documentUploadService : DocumentUploadService,  private notify: NotifyService,) {
        this.Comparator = comparator;
        this.editClicked = true;
        this.getDocumentUploadDetails();
        window.onresize = (e) => {
            this.ngZone.run(() => {
                this.windowHeight = window.innerHeight - this.offset;
                setTimeout(() => {
                    if (!this.GridOptions || !this.GridOptions.api) {
                        return;
                    }
                }, 500, true);
            });
        };

    }


    private getColumns(): Array<any> {
        const self = this;
        const columnDefs = new Array<any>();
        columnDefs.push({ headerName: 'ID', field: 'DocumentId', hide: true ,editable: false});
        columnDefs.push({ headerName: 'Document Type ID', field: 'DocumentTypeId', hide: true , editable: false});
        columnDefs.push({ headerName: 'Type', field: 'DocumentTypeName', hide: false , editable: true ,  cellEditor: 'agSelectCellEditor',
        cellEditorParams: {
          values: this.DocumentUploadDetails.DocumentTypes,
          cellRenderer: (params) => params.value.Name
        }
    });
        columnDefs.push({ headerName: 'Document', field: 'DocumentName', hide: false, editable: true });
        columnDefs.push({ headerName: 'Document Date', field: 'DocumentDate', hide: false , editable: true});

        columnDefs.push(
            {
                cellRenderer: function (p) {

                    if (p.node.data && p.node.data.DocumentId) {
                        var eSpan = self.getDeleteSpan();
                        eSpan.addEventListener('click', function () {
                            var self2 = self;
                            //self2.onEdit();
                        });
                        return eSpan;
                    }
                    else {
                        return '';
                    }
                }, comparator: this.comparator.StringComparator, width: 50, cellStyle: { textAlign: 'center' }, cellClass: 'align-center', headerName: "Edit", pinned: 'right'

            });


        columnDefs.push(
            {
                cellRenderer: function (p) {

                    if (p.node.data && p.node.data.DocumentId) {
                        var eSpan = self.getDeleteSpan();
                        eSpan.addEventListener('click', function () {
                            var self2 = self;
                            self2.Delete(p.node.data.DocumentId);
                        });
                        return eSpan;
                    }
                    else {
                        return '';
                    }
                }, comparator: this.comparator.StringComparator, width: 50, cellStyle: { textAlign: 'center' }, cellClass: 'align-center', headerName: "Delete", pinned: 'right'

            });


            this.editType = 'fullRow';

        return columnDefs;
    }

    onEdit() {
        // this.params =  this.GridOptions.api.getEditingCells;
        // this.editClicked = !this.editClicked;
        // this.params.api.setFocusedCell(this.params.node.rowIndex, 'action');
        // this.params.api.startEditingCell({
        //  rowIndex: this.params.node.rowIndex,
        //  colKey: 'action'
        // });
       }


    private getDeleteSpan() {
        var eSpan = document.createElement('a');
        eSpan.innerHTML = '<div style="cursor:pointer;max-width: 50px"><i class="far fa-trash-alt fontColor" aria-hidden="true"></i></div>';
        return eSpan;
    }

    GridHeight() {
        if (!this.windowHeight) {
            this.windowHeight = window.innerHeight - this.offset + 10;
        }
        return this.windowHeight;
    }

    private initGrid() {
        const self = this;
    }

    setGridOptions() {
        this.GridOptions = {
            columnDefs: this.getColumns(),
            enableFilter: true,
            enableColResize: true,
            animateRows: true,
            enableSorting: true,

            onGridReady: e => {
                if (!e || !e.api) {
                    return;
                }

                this.gridApi = e.api;

                this.setDefaultSortOrder();
            },
            onGridSizeChanged: () => this.GridOptions.api.sizeColumnsToFit(),



        };

    }

    onCellClicked($event){
        // check whether the current row is already opened in edit or not
        if(this.editingRowIndex != $event.rowIndex) {
          console.log($event);
          $event.api.startEditingCell({
            rowIndex: $event.rowIndex,
            colKey: $event.column.colId
          });
          this.editingRowIndex = $event.rowIndex;
        }
      }

    setDefaultSortOrder() {
        const defaultSortModel = [
            { colId: 'DocumentDate', sort: 'desc' }

        ];
        this.GridOptions.api.setSortModel(defaultSortModel);
    }


    onGridSizeChanged(params) {
        const gridWidth = document.getElementById('grid-wrapper').offsetWidth;
        const columnsToShow = [];
        const columnsToHide = [];
        let totalColsWidth = 0;
        const allColumns = params.columnApi.getAllColumns();
        for (let i = 0; i < allColumns.length; i++) {
            const column = allColumns[i];
            totalColsWidth += column.getMinWidth();
            if (totalColsWidth > gridWidth) {
                columnsToHide.push(column.colId);
            } else {
                columnsToShow.push(column.colId);
            }
        }
        params.columnApi.setColumnsVisible(columnsToShow, true);
        params.columnApi.setColumnsVisible(columnsToHide, false);
        params.api.sizeColumnsToFit();
    }

    private Delete(Id: number) {

            if (Id !== 0) {


                this.Error = '';
                this.documentUploadService
                    .deleteDocument(Id)
                    .then((result) => {
                        if (result) {
                            this.notify.success('Document Successfully Deleted');
                           // this.ClassficationOverrideDetailsEvent.next('init');
                        }
                    }).catch(err => {
                        this.notify.error('An Error Has Occured While Deleting Document');
                    });
            }

    }





    public getDocumentUploadDetails() {
        if (this.MgrStrategyId != null) {
            this.Loading = true;
            this.initGrid();

            //  this.spinner.show();
            this.documentUploadService.getDocumentUploadDetails(this.MgrStrategyId)
                .subscribe(data => {
                    this.DocumentUploadDetails = data;
                    this.ColumnDefs = this.getColumns();
                    this.Loading = false;

                    setTimeout(() => {
                        this.GridOptions.api.sizeColumnsToFit();
                        this.Loading = false;
                    }, 100, true);
                },
                    err => {
                        this.Error = 'An error has occurred. Please contact BSG';
                    },
                    () => {
                    });
        }
    }
}

根据建议的解决方案更新了代码

为了使用agSelectCellEditor,我通过了以下选项

  this.DocumentTypesForDropDown = this.DocumentUploadDetails.DocumentTypes.map(x => x.Name);

我还按照建议删除了对this.getColumns()的调用,并将其移至init方法

我的Init方法现在看起来像这样

   ngOnInit() {

        this.getDocumentUploadDetails();
        this.setGridOptions();
        this.setColumns();


    }

当我从服务中获取DocumentType时,可以通过在getDocumentUploadDetails方法中设置this.DocumentTypesForDropDown值来进行小的更改。

public getDocumentUploadDetails() {
        if (this.MgrStrategyId != null) {
            this.Loading = true;
            this.initGrid();

            //  this.spinner.show();
            this.documentUploadService.getDocumentUploadDetails(this.MgrStrategyId)
                .subscribe(data => {
                    this.DocumentUploadDetails = data;
                    this.DocumentTypesForDropDown = this.DocumentUploadDetails.DocumentTypes.map(x => x.Name);

                   // this.ColumnDefs = this.getColumns();
                    this.Loading = false;

                    setTimeout(() => {
                        this.GridOptions.api.sizeColumnsToFit();
                        this.Loading = false;
                    }, 100, true);
                },
                    err => {
                        this.Error = 'An error has occurred. Please contact BSG';
                    },
                    () => {
                    });
        }
    }
}

完成上述操作后,我没有出现任何错误,并且显示了空白网格

更新2

_documentTypes: any;
    get DocumentTypes(): any {
        return this._documentTypes;
    }
    @Input('DocumentTypes')
    set DocumentTypes(value: any) {
         this._documentTypes = value;
         if(this._documentTypes.length > 0) {
         this.DocumentTypesForDropDown = this._documentTypes.map(x => x.text);
         this.getDocumentUploadDetails();
        this.setGridOptions();
        this.setColumns();
         }
    }

1 个答案:

答案 0 :(得分:0)

您的代码有很多问题,我将尽力解决每个问题。

与下拉列表有关的主要问题,您的下拉列表具有以下代码:

columnDefs.push({
  headerName: 'Type', field: 'DocumentTypeName', hide: false, editable: true, cellEditor: 'agSelectCellEditor',
  cellEditorParams: {
    values: this.DocumentUploadDetails.DocumentTypes,
    cellRenderer: (params) => params.value.Name
  }

使用agSelectCellEditor时,可以传递给cellEditorParams的唯一参数是values(请参阅文档)。

因此,如果您想使用对象作为下拉菜单,则需要使用agRichSelectCellEditor来处理对象。 agrichselectcelleditor将具有cellRenderer参数,尽管这是ag-grid的企业功能。

因此,如果您希望在下拉列表中按名称列出选项,建议您创建一系列下拉列表问题,并在其中仅包含文档类型名称。

您可以执行以下操作:

this.DocumentTypesForDropDown = this.DocumentUploadDetails.DocumentTypes.map(x => x.Name);

这将包含所有文档类型名称的数组。然后,您可以将其作为下拉列表的参数提供给列定义,因此列定义应如下所示:

this.ColumnDefs.push({
      headerName: 'Type', field: 'DocumentTypeName', hide: false, editable: true, cellEditor: 'agSelectCellEditor',
      cellEditorParams: {
        values: this.DocumentTypesForDropDown
      }
    });

您可能遇到的另一个问题是下拉列表不会显示任何内容;这是因为在创建列定义之前,必须定义下拉菜单的值; cellEditorParams不采用动态参数。

在代码中继续在两个位置设置列定义:setGridOptions()方法和getDocumentUploadDetails()方法。

我建议在setGridOptions()getDocumentUploadDetails()方法中删除列定义的设置,而在ngOnInit()中进行设置。

我还为您的代码创建了简化的StackBlitz,这应该有助于更好地理解我的答案。