带有Angular的socket.io不会立即显示消息

时间:2016-06-04 13:24:06

标签: javascript angularjs node.js socket.io

我正在尝试使用socket.io和Angular创建instanse消息应用(聊天)。 我有2个文件:index.html,index.js如下所示。 聊天工作正常,当我按下"发送"按钮我在聊天窗口中没有看到消息。 用鼠标光标按下输入文本字段后,我只看到消息 ... 我做错了什么?

另外,我还看到了标签< li>作为案文的一部分。我希望这个标签是一个html标签,而不是文本字符串......

由于

的index.html

<html>
<head>
  <title>My Chat</title>
  <link rel="stylesheet" type="text/css" href="css/style.css">
  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
  <script src="/socket.io/socket.io.js"></script>
</head>
<body>
  <div ng-app="myApp" ng-controller="myCtrl">
    {{ message }}
    <form >
      <input autocomplete="off" ng-model="exampleText" type="text" />
      <button type='button' ng-click="submit()">
        Send
      </button>
    </form>
  </div>
  <script>

   var app=angular.module("myApp", []);
   var socket = io();
   app.controller("myCtrl", function($scope) {
     $scope.message='';
     $scope.submit=function(){
      socket.emit('chat message', angular.copy($scope.exampleText));
      $scope.exampleText='';
      return false; 
    }
    socket.on('chat message', function(msg){
      $scope.message=$scope.message+" <li> "+ msg;
    });
  });

</script>
</body>
</html> 

index.js

var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.use(express.static(__dirname + '/'));
app.get('/', function(req, res){
    res.sendFile(__dirname + '/index.html');
});

io.on('connection', function(socket){
    console.log('a user connected');


    socket.on('chat message', function(msg){
        io.emit('chat message', msg);
    });


    socket.on('disconnect', function(){
        console.log('user disconnected');
    });


});

http.listen(3000, function(){
    console.log('listening on *:3000');
});

2 个答案:

答案 0 :(得分:7)

首先,消息延迟。查看聊天消息处理程序:

socket.on('chat message', function(msg){
  $scope.message=$scope.message+" <li> "+ msg;
});

- 这里的问题是消息更新发生在范围摘要循环之外。请尝试以下方法:

socket.on('chat message', function(msg){
  $scope.$apply(function() {
     $scope.message=$scope.message+" <li> "+ msg + "</li>";
  });
});

接下来,如果要删除显示的“li”标记,则需要停止在控制器中构建HTML并直接显示传入的消息。这可以通过使“消息”成为一组消息来实现。在HTML布局中,替换:

{{ message }}

<ul>
    <li ng-repeat="message in messages">{{message}}</li>
</ul>

然后在控制器中替换

$scope.message='';

$scope.messages = [];

最后将聊天消息处理程序更改为:

socket.on('chat message', function(msg){
    $scope.messages.push(msg);
});

这样就可以了。

答案 1 :(得分:0)

问题是您使用的socket.on来自index.html,它位于您的angularjs应用范围之外,并且它不会监视该方法调用。

为了避免这样的问题,您可以像这样使用$scope.$apply

socket.on('chat message', function(msg) {
  $scope.$apply(function() {
     ...
  }
});

或者更好地使用完全附加到$scope的{​​{3}},并且不要调用其他方法

// in the top-level module of the app
angular.module('myApp', [
  'btford.socket-io',
  'myApp.MyCtrl'
]).
factory('mySocket', function (socketFactory) {
  return socketFactory();
}).
controller('MyCtrl', function (mySocket) {
  // ...
});