【问题标题】:Angular 1.6.9 and socket.io chat applicationAngular 1.6.9 和 socket.io 聊天应用程序
【发布时间】:2018-09-15 23:44:53
【问题描述】:

到目前为止,我为使用 Angular 和 Socket.io 的聊天应用程序开发了以下代码。我似乎无法修复的关键部分是“nickWrap”。它由消息“输入昵称”、输入文本框和提交按钮组成。如果昵称已经存在,昵称将被传递到服务器,它会在其中检查一个数组。如果不是,那么它应该返回成功,那么我应该禁用表单并显示另一个 div 内容。但似乎在我收到一条成功消息后,我必须再次在输入文本框中输入一些内容,然后它才会被禁用。此外,禁用此表单后的在线用户列表并不总是正确显示在使用 ng-repeat 的选择中。总有一块空地。另外,当另一个用户连接时,现有用户无法在选择列表中动态看到新用户,而新用户可以看到旧用户。如果任何一个用户断开连接,则其他用户客户端的选择列表也不会动态更新列表。我对 Angular、nodejs、socket.io 和所有这些都很陌生

客户代码是:

<!doctype html>
<html>
    <head>
        <title>chat</title>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.js"></script>

        <script src="/socket.io/socket.io.js"></script>
        </script>
        <!--<script src="app.js"></script>-->
        <script>
            var app = angular.module("myApp", []);
            var socket = io();
            var storedName;
            app.controller("myCtrl", function($scope) {
                $scope.ok=false;
                $scope.chatOK=false;
                $scope.myFunc = function () {
                    socket.emit('new user',$scope.nickname,function(data){
                        if(data){
                            alert('You picked good nickname');
                            $scope.ok=true;
                        }
                        else
                        {
                            alert('Pick a different Nickname');
                            $scope.ok=false;
                        }
                    });
                    //storedName=$scope.nickname;
                    $scope.nickname="";
                }
                $scope.sendRequest=function(){
                    alert('Chat Request sent to '+$scope.selector+' !');
                    $scope.chatOK=true;
                }
                socket.on('usernames',function(data){
                    $scope.names=data;
                    alert($scope.names);
                });
            });
        </script>
    </head>
    <body ng-app="myApp" ng-controller="myCtrl">
        <div id="nickWrap">
            <span>Enter NickName:</span>
            <div>
                <form ng-submit="myFunc()">
                    <input type="text" placeholder="random nickname" ng-model="nickname" ng-disabled="ok">
                    <input type="submit" ng-disabled="ok">
                </form>
            </div>
            <p>
            <div id="chatWrap" ng-show="ok">
                <select name="sometext" size="20" style="width:200px" ng-model="selector">
                    <option ng-repeat="namelist in names">{{namelist}}</option>
                </select><br/>
                <Strong>LIST OF ONLINE USERS</Strong>
            </div>
        </div>
        <div id="requestWrap" ng-show="selector">
            <form ng-submit="sendRequest()">
                <input type="submit" value="Send Chat Request to {{selector}}"/>
            </form>
        </div>
        <div id="messageWrap" ng-show="chatOK">
            MESSAGES WILL APPEAR HERE SOON!!!!!!
        </div>
    </body>
</html>

服务器代码是:

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var nicknames=[];

app.get('/', function(req, res){
  res.sendFile(__dirname + '/index.html');
});
app.post('/log', function(req, res){
  console.log('someone connected');
});

io.on('connection', function(socket){
    console.log('a user '+socket.id+' connected');
    socket.on('disconnect', function(){
      console.log('user '+socket.id+' disconnected');
      //if(!socket.nickname) return;
      nicknames.splice(nicknames.indexOf(socket.nickname),1);
      socket.emit('usernames',nicknames);
      //updateNames();
    });
    socket.on('chat message', function(msg){
      console.log('message from user '+socket.id+' : ' + msg);
    });
    socket.on('new user',function(data, callback){
      console.log(data);
      if(nicknames.indexOf(data)!=-1){
        callback(false);
      }
      else{
        callback(true);
        socket.nickname=data;
        nicknames.push(data);
        //updateNames();
        socket.emit('usernames',nicknames);
      }
    });
    socket.on('chat message', function(msg){
      io.emit('chat message', msg);
    });
    //function updateNames(){
      //socket.emit('usernames',nicknames);
    //}
});

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

【问题讨论】:

    标签: angularjs node.js socket.io


    【解决方案1】:

    您的前 2 个问题(输入禁用和 ng-repeat)已关联。

    在 angularJS 中,当您调用 socket.emit 之类的服务时,您会脱离 angular 的上下文并且 $scope 不会更新。

    设置变量后,您需要强制调用 $scope.$apply()

    socket.emit('new user',$scope.nickname,function(data){
      if(data){
        alert('You picked good nickname');
        $scope.ok=true;
      } else {
        alert('Pick a different Nickname');
        $scope.ok=false;
      }
      $scope.$apply();
    });
    

    【讨论】:

    • 好吧,$scope.$apply() 对 ng-disabled 有效,但对 ng-repeat 无效,尽管我使用 $timeout 而不是 $apply()。对于选择 ng-repeat 问题,我使用了以下
    猜你喜欢
    • 2016-12-20
    • 1970-01-01
    • 1970-01-01
    • 2014-08-13
    • 2014-10-05
    • 1970-01-01
    • 1970-01-01
    • 2016-09-08
    • 2012-08-11
    相关资源
    最近更新 更多