Angular 4中Socket.IO无法赋值全局变量及调用函数问题
解决Angular 4中Socket.io回调里无法访问组件变量/方法的问题
你遇到的这个问题其实是JavaScript里this指向的经典坑——普通function()回调里的this已经不是你的Angular组件实例了,而是回调函数自身,所以自然没法访问组件的sessionId或者调用组件方法。下面给你三种最常用的解决方案,都是Angular开发里的常规操作:
方案1:使用箭头函数(最推荐)
箭头函数不会绑定自己的this,它会直接继承外层上下文的this(也就是你的组件实例)。把回调里的function()换成箭头函数就行:
public sessionId; private socket; // 建议把socket设为组件属性,方便后续复用 constructor(){ this.socket = io.connect('http://**.***.***.***:****'); this.socket.on('connect', (data) => { // 换成箭头函数 console.log('user connected'); this.socket.emit('add user', { userId: uid }); }); this.socket.on('create channel', (data) => { // 这里也换成箭头函数 console.log(data); this.sessionId = data.sessionId; // 现在this指向组件实例,赋值正常 this.yourComponentMethod(); // 也能直接调用组件里的方法了 }); } // 示例组件方法 yourComponentMethod() { console.log('调用组件方法成功'); }
方案2:提前保存组件的this到变量
如果习惯用普通函数回调,可以在回调外面先把组件的this存成一个变量(比如self或that),然后在回调里用这个变量代替this:
public sessionId; constructor(){ const self = this; // 保存组件实例的this const socket = io.connect('http://**.***.***.***:****'); socket.on('connect', function(data) { console.log('user connected'); socket.emit('add user', { userId: uid }); }); socket.on('create channel', function(data) { console.log(data); self.sessionId = data.sessionId; // 用self访问组件属性 self.yourComponentMethod(); // 调用组件方法 }); }
方案3:用bind()绑定this
通过bind()方法把回调函数的this强制绑定到组件实例上,这种写法稍显繁琐,但也是可行的:
public sessionId; constructor(){ const socket = io.connect('http://**.***.***.***:****'); socket.on('connect', function(data) { console.log('user connected'); socket.emit('add user', { userId: uid }); }); socket.on('create channel', function(data) { console.log(data); this.sessionId = data.sessionId; this.yourComponentMethod(); }.bind(this)); // 绑定组件的this到回调函数 }
额外小建议
尽量把socket实例声明为组件的属性(比如上面方案1里的private socket),而不是constructor里的局部变量,这样在组件的其他生命周期钩子或方法里也能方便地使用socket,更符合Angular组件的设计逻辑。
内容的提问来源于stack exchange,提问作者Amith Dissanayaka
相关产品推荐
相关产品推荐

