在Angular模板中传递回调函数时如何保留this执行上下文?
问题根本原因
你遇到的this丢失是两个问题共同导致的:
- Angular模板中直接传递类普通方法作为参数时,传递的只是独立的函数引用,脱离了所属组件实例的上下文,直接调用时
this自然指向undefined(严格模式下) - 你当前
sendDeleteRequest中cbk()()的写法默认要求cbk执行后返回一个可执行函数,普通的f方法直接调用会返回undefined,再加一层调用本身就会报错,和你之前尝试返回lambda函数的写法不匹配是因为你没有给外层函数绑定上下文。
可行解决方案(按推荐优先级排序)
方案1:将f定义为箭头函数类属性(最省心,无需修改模板和现有调用逻辑)
箭头函数会在定义时就绑定所在上下文,永远指向所属组件实例:
// 把原来的f方法改成箭头函数类属性 f = () => { console.log(this.owner) }
同时修正sendDeleteRequest中的调用逻辑,去掉多余的第二层括号(如果不需要返回函数的场景):
sendDeleteRequest(btn: MatButton, cbk: any) { cbk() }
模板不需要做任何修改,直接用原来的写法即可。
方案2:模板传参时手动绑定this
如果不想改f的定义,可以在模板传递参数时给f绑定当前组件上下文:
<button mat-raised-button (click)="sendDeleteRequest(deleteCredBtn, f.bind(this))" color="warn" #deleteCredBtn="matButton">Delete</button>
同样要修正sendDeleteRequest的调用逻辑为cbk()即可。
方案3:保留双层调用逻辑的适配方案
如果你确实需要cbk()()的双层调用写法(比如需要先做前置逻辑再返回执行函数),要给外层的f绑定上下文:
首先保留f返回箭头函数的写法:
f() { return () => { console.log(this.owner) } }
然后模板传参时绑定this:
<button mat-raised-button (click)="sendDeleteRequest(deleteCredBtn, f.bind(this))" color="warn" #deleteCredBtn="matButton">Delete</button>
原来的sendDeleteRequest中cbk()()的写法可以不变。
你之前尝试的方案失效原因
- 在f内部赋值
self = this:f调用时this已经是undefined,self自然也是undefined,没有作用 - 返回lambda函数但未绑定外层f的上下文:外层f调用时
this是undefined,返回的箭头函数继承的上级上下文也是undefined - 调用时
bind(this)写法错误:你需要在执行cbk之前绑定,也就是cbk.bind(this)(),而不是先执行cbk()再绑定,先执行的阶段已经丢失了上下文。
内容的提问来源于stack exchange,提问作者Antonio Santoro
相关产品推荐
相关产品推荐

