【问题标题】:Ag-Grid update rowdata from parentAg-Grid 从父级更新行数据
【发布时间】:2020-03-06 05:56:02
【问题描述】:

我有两个组件,一个是我有一些选择(userType,user)和一个用于添加所选用户的按钮。

另外一个带有 ag-grid,我应该在其中显示来自上述组件的用户。

我之所以将它们分成不同的组件是因为我的老板想在应用程序的另一部分重用第一个,网格我也打算将它与类似的组件一起使用并要求我这样做方式。

我已经在组件开头传递了值,但我不知道如何检测数据何时更改以刷新网格。

父组件.HTML:

<div class="modal-body">
    <label>Reviewers are optional, select a review type and reviewer below to add to the submission 
        as reviewers</label>
    <div class="clr-row">
        <div class="clr-col-12 clr-col-md-6 clr-col-lg-4 clr-col-xl-4">
            <clr-select-container>
                <label>Review Type</label>
                <select clrSelect name="reviewerTypes" (change)="onChange(currentReviewerType)" 
                    [(ngModel)]="currentReviewerType">
                    <option [value]="" selected disabled hidden>
                        Choose value
                    </option>
                    <option *ngFor="let reviewType of reviewerTypes" [ngValue]="reviewType">
                        {{reviewType.reviewType}}
                    </option>
                </select>
            </clr-select-container>
        </div>
        <div class="clr-col-12 clr-col-md-6 clr-col-lg-4 clr-col-xl-4">
            <clr-select-container>
                <label>Reviewer</label>
                <select clrSelect name="options" [(ngModel)]="currentReviewer">
                    <option value="" selected disabled hidden>Choose value</option>
                    <option *ngFor="let reviewer of reviewers" [ngValue]="reviewer">
                        {{reviewer.user}}
                    </option>
                </select>
            </clr-select-container>
        </div>
    </div>
    <div class="clr-row" style="margin-top: 20px;">
        <div class="clr-col-12 clr-col-md-6 clr-col-lg-4 clr-col-xl-3">
            <clr-button-group class="btn-primary">
                <clr-button (click)="addReviewer()" >Add Reviewer</clr-button>
            </clr-button-group>
        </div>
    </div>
</div>
<div class="modal-footer">
    <app-q-sub-reviewer-grid style="width: 100%;" [reviewersAdded]='reviewersAdded'></app-q-sub- 
    reviewer-grid>
</div>

parentComponent.ts:

ngOnInit() {
   this.dataService.GetReviewerTypes().subscribe( response => this.reviewerTypes = response, error => 
   console.log(error));
   this.mockType = {id:1, reviewType:"type"}
   this.mockReviewer = {userId:1,user:"Samel"}
   //////////// this is a mock to see if it was working, i'll remove this lates
   let reviewerToAdd = {reviewerType:this.mockType, reviewer:this.mockReviewer}
   this.reviewersAdded.push(reviewerToAdd)
   this.reviewersAdded.push(reviewerToAdd)
   this.reviewersAdded.push(reviewerToAdd)
}

onChange(selection){
   let reviewerId = selection;
   this.dataService.GetReviewersByType(reviewerId.id).subscribe( (response)=> {
     this.reviewers = response
     this.currentReviewer = response[0]
   }, 
   error => console.log(error));
}

addReviewer(){
   console.log(this.currentReviewer)
   let reviewerToAdd = {reviewerType:this.currentReviewerType, reviewer:this.currentReviewer}
   this.reviewersAdded.push(reviewerToAdd)
   console.log(this.reviewersAdded)
}

childGridComponent.HTML:

<ag-grid-angular style="width: 100%; height: 118px;" class="ag-theme-balham" 
   [rowData]="rowData"
   [columnDefs]="columnDefs"
   [animateRows]="true" 
   [enableSorting]="true" 
   [enableFilter]="true" 
   (gridReady)="onGridReady($event)" 
   (gridSizeChanged)="onGridSizeChanged($event)">
</ag-grid-angular>

childGridComponent.ts

@Input('reviewersAdded') reviewersAdded: any[];

constructor() {
   this.columnDefs = [
     { headerName: "Review Type", sortable: true, filter: true, field: 'reviewerType', 
      suppressSizeToFit: false },
     { headerName: "Reviewer", sortable: true, filter: true, field: 'reviewer', suppressSizeToFit: 
      false }
   ]
   this.defaultColDef = { filter: true };
}

ngOnInit() {
}

onGridReady(params) {
   this.gridApi = params.api;
   this.gridApi.sizeColumnsToFit();
   this.gridColumnApi = params.columnApi;
   this.reviewersAdded.forEach(item => {
   this.rowData.push({ reviewerType: item.reviewerType.reviewType, reviewer: item.reviewer.user })
      var res = this.gridApi.updateRowData({ add: [{ reviewerType: item.reviewerType.reviewType, 
      reviewer: item.reviewer.user }] });
      console.log(res);
   })
}

//////this ngOnChanges is not working
ngOnChanges(changes: SimpleChanges) {
   console.log(this.reviewersAdded)
}

onGridSizeChanged(params: GridSizeChangedEvent) {
   params.api.sizeColumnsToFit();

}

【问题讨论】:

    标签: angular parent-child ag-grid


    【解决方案1】:

    我认为ngOnChanges 没有被解雇,因为它是一个数组,数组和对象是引用类型。 ngOnChanges 只会在数组或对象的内存位置发生变化时启动。所以你必须不可变地修改数组。

    ngOnInit() {
       this.dataService.GetReviewerTypes().subscribe( response => this.reviewerTypes = response, error => 
       console.log(error));
       this.mockType = {id:1, reviewType:"type"}
       this.mockReviewer = {userId:1,user:"Samel"}
       //////////// this is a mock to see if it was working, i'll remove this lates
       let reviewerToAdd = {reviewerType:this.mockType, reviewer:this.mockReviewer}
       this.reviewersAdded.push(reviewerToAdd)
       this.reviewersAdded.push(reviewerToAdd)
       this.reviewersAdded.push(reviewerToAdd)
       // have to spread the reviewerToAdd object as well since it's a reference type
       this.reviewersAdded = [...this.reviewersAdded, {...reviewerToAdd }];
    }
    ....
    addReviewer(){
       console.log(this.currentReviewer)
       let reviewerToAdd = {reviewerType:this.currentReviewerType, 
       reviewer:this.currentReviewer}
       this.reviewersAdded = [...this.reviewersAdded, { ...reviewerToAdd }];
       console.log(this.reviewersAdded)
    }
    

    通过这些更改,查看ngOnChanges 是否激活。

    如果ngOnChanges 激活,您可能需要更新行数据,甚至可能使用gridApi 或发出另一个http 请求并查看数据是否更改。

    【讨论】:

    • 它现在可以使用ngOnChanges,我尝试更新gridApi,但一开始,它会抛出一个错误,因为它是undefined,也是this.reviewersAdded = [...this.reviewersAdded, { ...reviewerToAdd }]; 这一行复制了数组,它会再次添加新的 reviewerToAdd 以及整个 this.reviewersAddes
    • 所以应该只有一个吗? reviewersAdded 应该只有一个。那就试试this.reviewersAdded = [...{reviewerToAdd}];
    • 不应该有很多,但是如果我已经有{"ricardo", "alif"},当我尝试添加另一个时,比如说汤姆,我会得到{"ricardo", "alif", "ricardo", "alif", "tom"}
    • 嗯...不确定,这不应该发生。
    • 抱歉是我的错哈哈现在工作正常,那条线没问题
    【解决方案2】:

    您可以在代码中使用现有的 Input Eventemitter:

    在您的子(网格)组件中 定义您的 dataSource 或 reviewrs 属性。

    dataSource: any; // your reviewers that feeds the table.
    get reviewersAdded() {
       return this.dataSource;
    }
    
    @Input() set reviewersAdded(val: any) {
        if (this.dataSource !== val) {
           this.dataSource = val; // update the datasource
       }
    }
    

    【讨论】:

    • 我猜 rowData 相当于上面解决方案中的 dataSource
    猜你喜欢
    • 2020-06-22
    • 1970-01-01
    • 2021-03-10
    • 1970-01-01
    • 2021-12-06
    • 1970-01-01
    • 2021-09-21
    • 2021-11-20
    • 2016-06-12
    相关资源
    最近更新 更多