Angular子组件如何调用数据配置中传入的父组件自定义函数
实现步骤
这种配置化传回调的场景不需要单独定义@Output(),直接接收传入的函数调用即可,核心要解决父组件方法的this指向丢失问题,具体实现如下:
父组件侧处理(重点解决this指向问题)
把类方法直接赋值给配置项的dataKeyFn时,默认会丢失类实例的this上下文,直接调用会导致方法内部访问父组件属性/方法时报错,两种写法可以规避:
- 用箭头函数定义事件处理方法(推荐)
// parent.ts interface ColDef { dataKey: string; dataKeyFn: (val: any, col: ColDef) => void; } export class ParentComponent { // 箭头函数会自动绑定当前组件实例的this handleFlagClick = (cellValue: number, col: ColDef) => { console.log('flag列点击,当前值:', cellValue, '列配置:', col); // 此处可正常访问父组件的其他属性、调用其他方法 } handleScoreClick = (cellValue: number, col: ColDef) => { console.log('score列点击,当前值:', cellValue, '列配置:', col); } cols: ColDef[] = [ { dataKey: 'flag', dataKeyFn: this.handleFlagClick }, { dataKey: 'score', dataKeyFn: this.handleScoreClick } ] rows = [{flag:1, score:10},{flag:2, score:9},{flag:10, score:1}] } - 普通类方法显式绑定this
如果习惯写普通类方法,在配置项赋值时手动绑定父组件实例即可:// 普通方法定义 handleFlagClick(cellValue: number, col: ColDef) { // 业务逻辑 } cols: ColDef[] = [ // 手动绑定this上下文 { dataKey: 'flag', dataKeyFn: this.handleFlagClick.bind(this) }, // ...其他列配置 ]
父组件模板保持原有写法即可,只需要通过输入属性把cols和rows传给子组件:
<!-- parent.html --> <myEl [cols]="cols" [rows]="rows" />
子组件侧接收配置、调用回调
子组件只需要通过@Input()接收传入的配置和行数据,在面板点击事件中找到对应列的处理函数,按要求传参调用即可:
// myEl.component.ts import { Component, Input } from '@angular/core'; interface ColDef { dataKey: string; dataKeyFn: (val: any, col: ColDef) => void; } @Component({ selector: 'myEl', template: ` <div class="panel-wrap"> <!-- 遍历所有行渲染面板 --> <div *ngFor="let row of rows" class="row-group"> <!-- 遍历列配置渲染每个可点击项 --> <div *ngFor="let col of cols" class="click-panel" (click)="triggerColHandler(row, col)" > {{ row[col.dataKey] }} </div> </div> </div> ` }) export class MyElComponent { @Input() cols: ColDef[] = []; @Input() rows: Record<string, any>[] = []; triggerColHandler(currentRow: Record<string, any>, currentCol: ColDef) { // 先校验是否配置了处理函数,避免空配置报错 if (typeof currentCol.dataKeyFn !== 'function') return; // 取当前单元格的值,和列配置一起作为入参传入 const cellValue = currentRow[currentCol.dataKey]; currentCol.dataKeyFn(cellValue, currentCol); } }
关键说明
- 这种传回调的方式非常适合配置化渲染场景(动态表格、动态面板、低代码渲染器),不需要为每个事件单独定义
@Output(),扩展列配置时不需要修改子组件逻辑 - 一定不要忽略this指向问题,90%的同类报错都是因为父组件传入的方法丢失了上下文
- 调用前做函数类型校验,可以兼容部分列不需要绑定点击事件的场景
内容的提问来源于stack exchange,提问作者Silvio
相关产品推荐
相关产品推荐

