【问题标题】:socket.io with Angular doesn't display message instantly带有 Angular 的 socket.io 不会立即显示消息
【发布时间】:2016-06-16 21:04:12
【问题描述】:

我正在尝试使用 socket.io 和 Angular 创建即时消息应用程序(聊天)。 我有 2 个文件:index.html 和 index.js 如下所示。 聊天工作正常期望当我按下“发送”按钮时,我不会立即在聊天窗口中看到消息。 我只看到消息一旦我用鼠标光标按下输入文本字段... 我做错了什么?

i 另外,我还看到标签

  • 作为文本的一部分。我希望这个标签是一个 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');
    });
    
  • 【问题讨论】:

    标签: javascript angularjs node.js socket.io


    【解决方案1】:

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

    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);
    });
    

    这样就可以了。

    【讨论】:

      【解决方案2】:

      问题是您正在使用来自 index.htmlsocket.on,这超出了您的 angularjs 应用程序范围,并且它不会监视该方法调用。

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

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

      或者更好地使用完全附加到$scopeangularjs component for socket.io,并且您不要调用其他方法

      // 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) {
        // ...
      });
      

      【讨论】:

        猜你喜欢
        • 2011-02-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多