javascript - 无法读取 'undefined' 的属性推送

标签 javascript angularjs sockets scope socket.io

app.controller('ctrl', function($scope){
    var socket = io.connect();

    this.messages = [];

    this.sendMessage = function(){
        socket.emit('new message', this.input_message);
        this.input_message = '';
    }

    socket.on('new message', function(data){
        this.messages.push(data);
    });
});

我正在获取套接字发出的数据,但是当我尝试将该数据推送到 messages 数组中时,它显示错误无法读取未定义的属性推送。我做错了什么?

最佳答案

这不起作用,因为您在套接字范围 (this.messages.push(data)) 中调用 this,这与 Controller 范围不同。这就是为什么 this.messagesundefined,因为它是在 Controller 函数作用域中声明的,而不是在套接字回调函数作用域中声明的。在 javascript 中,每个函数都有自己的作用域(箭头函数除外)。

建议

app.controller('ctrl', function($scope){
   var ctrlContext = this;
   var socket = io.connect();

   //using the this keyword here means that
   //it's in the controller function scope.
   this.messages = [];

   this.sendMessage = function(){
      socket.emit('new message', this.input_message);
      this.input_message = '';
   }

   socket.on('new message', function(data){
      //inside the callback function we have a different
      //scope, which means that this.messages will be undefined.
      //but by referencing the controller function scope, you
      //are now able to use the messages property set the
      //outer (controller function) scope.
      ctrlContext.messages.push(data);

      //as you stated, you will also have to call $scope.$apply
      //or else the digest cycle will not be triggered.
   });
});

但是,如果您想在套接字回调函数中使用 this 关键字,您可以使用 function.prototype.bind 来实现。方法,它允许您设置执行函数的上下文。

示例

var person = {
   name: 'John Doe';
}

//Create function and bind to context person    
var changeName = function() {
   this.name = 'Peter Smith';
}.bind(person);

console.log(person); // {name: 'John Doe'}

changeName(person);

console.log(person); // {name: 'Peter Smith'}

对于你的解决方案来说,它会是这样的:

app.controller('ctrl', function($scope){
   var socket = io.connect();

   this.messages = [];

   var callback = function(data){
      this.messages.push(data);
   }.bind(this);

   socket.on('new message', callback);
});

关于javascript - 无法读取 'undefined' 的属性推送,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39290263/

相关文章:

javascript - 使用 formData 上传文件返回未定义的文件数组

javascript - 如何将 Selenium 用于桌面应用程序?

windows - 测试套接字连接的好工具?

c++ - setsockopt 返回错误 10014

java - 线程卡在 readUTF() 中

javascript - 从 JavaScript 检测 Flash 版本

javascript - 在 express 中使用 sendfile 作为静态 html 文件路由的一部分时,会下载关联的 .js 和 .css 文件,但不会应用。

angularjs - 通过 Node.js 而不是像 Xampp 这样的服务器来运行 AngularJS Web 应用程序的实际优势是什么?

javascript - 为 Angular Material $mdDialog 提供 Angular ui-router 状态的 url

javascript - 错误 : _. get 不是函数