Angular中Subject订阅方法内控制台无法访问组件根变量的问题咨询
这种情况我之前在Angular项目里也碰到过,主要是异步回调的上下文绑定和调试器作用域映射这两个因素导致的,具体拆解下:
为什么会出现这个问题?
回调函数的
this绑定问题
如果你在subscribe里用的是普通函数作为回调(比如this.someSubject.subscribe(function(data) { ... })),那这个函数内部的this会指向Observable的执行上下文,而不是你的组件实例。这时候你在断点hover时,调试器会顺着作用域链找到上层的组件this,所以能看到this.nodes;但直接在控制台输入this.nodes时,this是回调函数的上下文,自然就返回undefined了。调试器与编译后代码的映射偏差
Angular项目用TypeScript编译后,异步回调(比如subscribe里的箭头函数)有时候会被Zone.js或者编译工具包装,导致调试器在断点时的this上下文没有正确映射到组件实例。虽然调试器能通过作用域链识别到组件的this(所以hover能看到),但控制台直接访问this时,可能指向的是包装后的上下文对象。
怎么在控制台访问到this.nodes?
给你几个实用的解决办法:
提前缓存组件上下文
在回调函数外部或者开头,把组件的this存到一个变量里,比如:// 组件方法里 someMethod() { const self = this; // 缓存组件的this this.someSubject.subscribe(data => { // 在这里打调试断点 console.log(self.nodes); // 控制台输入self.nodes就能访问到 }); }断点触发后,直接在控制台输入
self.nodes就能拿到你要的变量了。用Chrome调试器的
$r快捷方式
Chrome DevTools里有个小技巧:当你在组件的任意代码处断点时,控制台输入$r可以直接获取当前选中的组件实例(需要确保Elements面板里选中了对应的组件DOM元素)。之后直接输入$r.nodes就能访问到这个属性。确保用箭头函数作为回调
把subscribe的回调改成箭头函数,这样this会始终绑定到组件实例:this.someSubject.subscribe((data) => { // 这里的this就是组件实例 // 断点时控制台输入this.nodes应该就能正常访问了 });有时候调试器可能需要你重新触发断点或者刷新页面,才能正确识别
this的绑定。
内容的提问来源于stack exchange,提问作者A. Morel

