我正在使用socket io angular 2(typescript)和nodejs作为后端服务器构建一个简单的聊天应用程序 我有这个功能,当我点击连接按钮
时,它可以正常工作
connectUser(name){
if (name == null || name == ""){
return console.log('you must enter a valid username');
}
this.username = name;
this.socket.emit('add-user',name);
//load connected users in the user-window section
this.socket.emit('request-users',{data:'request users success'});
var connecctedUsersListener$ = Observable.fromEvent(this.socket,'users');
connecctedUsersListener$.subscribe((observer:any)=>{
this.users = observer;
},(err)=>{
if(err) throw err;
},()=>{
console.log('complet');
});
//load messages and keep track of Them
this.socket.emit('request-messages',{data:'request Messages success'});
var messageListener$ = Observable.fromEvent(this.socket,'message');
messageListener$.subscribe((observer:any) =>{
this.messages = observer;
})
}
然而,每当用户尝试连接时我尝试使用bootbox.prompt,所以我将所有代码包装在这个简单的函数中
addUser(){
bootbox.prompt('what is your name ',function(name){
connectUser(name); // this is the function in the first code snippet
});
}
我得到了这个奇怪的错误无法读取未定义的属性'emit' 我该如何解决这个问题?这里有什么问题?
答案 0 :(得分:3)
当您从addUser调用connectUser时,您正在从另一个函数(显然是回调)中执行此操作。
Javascript将“ this ”绑定到您正在使用的包装器函数,并且该函数没有“ socket ”成员。
当您直接从连接按钮调用函数 connectUser 时,您可能正在从对象内联调用它,因此,' this '绑定到对象上确实包含' socket '成员。
查看以下代码段,了解“function(){}”包装器对您的影响:
class Whatever {
socket: { emit: string }
constructor()
{
this.socket = { emit: 'works' };
}
doSomething()
{
console.warn(this.socket.emit);
}
works()
{
this.doSomething();
(() => this.doSomething())();
}
doesntWork()
{
(function () { this.doSomething() })();
}
}
let obj = new Whatever();
obj.works();
obj.doesntWork();
基本上你可以改变这个:
function(name) { connectUser(name); }
对于此
(name) => connectUser(name)
它应该有用。