Angular跨类调用函数问题:this指向异常
this指向错误的问题 这个问题其实是JavaScript中this绑定机制导致的典型场景——当你把组件的方法作为输入传递给指令后,指令调用该方法时,this的指向会从组件实例变成指令实例,自然就找不到组件里的router、selectedInvoiceDesign这些属性了。
问题根源
你在InvoiceDesignListPage里定义的loadForm是普通函数,它的this指向是由调用它的上下文决定的。当指令CheckAuthorizationOnClickDirective里调用this.checkAuthOnClick()时,调用上下文是指令实例,所以loadForm里的this就变成了指令,而非组件,这就是触发异常的原因。
三种可行的解决方案
根据你的代码结构,推荐以下几种方式来修复:
1. 模板中用箭头函数传递方法
在组件模板使用指令时,用箭头函数包裹要传递的方法,这样箭头函数会捕获组件的this上下文:
<!-- InvoiceDesignListPage的模板 --> <button checkAuthorizationOnClick [allowedClaim]="yourClaimValue" [checkAuthOnClick]="() => loadForm()" > 点击加载表单 </button>
这种方式最直观,不需要修改组件类的代码,适合简单场景。
2. 在组件类中绑定this到方法
在组件的构造函数里,用bind()把loadForm的this固定为组件实例,然后传递绑定后的方法:
// InvoiceDesignListPage类 export class InvoiceDesignListPage { loadFormBound: () => void; constructor(private router: Router) { // 绑定this到组件实例 this.loadFormBound = this.loadForm.bind(this); } loadForm() { this.router.navigate(['/ayarlar/fatura-gorsel/duzenle', this.selectedInvoiceDesign.Id]); } }
然后模板里传递绑定后的方法:
<button checkAuthorizationOnClick [allowedClaim]="yourClaimValue" [checkAuthOnClick]="loadFormBound" > 点击加载表单 </button>
这种方式内存更友好,适合需要多次复用方法的场景。
3. 把组件方法定义为箭头函数
直接将loadForm定义为箭头函数,这样它的this会始终绑定组件实例,不需要额外处理:
// InvoiceDesignListPage类 export class InvoiceDesignListPage { // 用箭头函数定义方法 loadForm = () => { this.router.navigate(['/ayarlar/fatura-gorsel/duzenle', this.selectedInvoiceDesign.Id]); }; }
然后模板里直接传递方法引用:
<button checkAuthorizationOnClick [allowedClaim]="yourClaimValue" [checkAuthOnClick]="loadForm" > 点击加载表单 </button>
这种方式代码最简洁,但每个组件实例都会创建一个新的函数副本,对于大量实例的组件来说可能有轻微的内存开销,不过大多数场景下可以忽略。
验证修改
无论用哪种方式,修改后再触发指令的点击事件,loadForm里的this都会指向InvoiceDesignListPage组件实例,router.navigate就能正常执行了。
内容的提问来源于stack exchange,提问作者ebruszl

