2016-11-11 51 views
0

我正在写一个基于Web的游戏,让你投标卡,并与其他玩家交易它们后进行查看更新不及时。对于这个应用程序,我使用Node,Express,MongoDB和Angular。AngularJS模型变化

的视图显示玩家的头像和名字与他们的连接状态一起。这种连接状态保存在游戏模式,但也可以通过socket.io的WebSockets跟踪的实时性。

当玩家加入游戏时,服务器会向所有客户端发送消息。然后,客户机检查,如果消息是通过比较游戏ID意味着他们。

socketService.on("playerConnection", function(data) { 
    if (data.gameId === gameId) { 
     handlePlayerConnection(data); 
    } 
}); 

如果消息是为我们的客户,将数据传递给函数“handlePlayerConnection”。

function handlePlayerConnection(data) { 
    if ($scope.game) { 
     for (var i = 0; i < $scope.game.players.length; i++) { 
      if ($scope.game.players[i].user.id === data.userId) { 
       $scope.game.players[i].isConnected = data.connected; 
      } 
     } 
    } 
} 

在视图中,我简单玩家化身绑定到“isConnected”,所以它显示了当一个玩家连接/断开/隐藏。

每隔一段时间,游戏模型都会发生变化(很明显),服务器会通过套接字告诉客户端刷新$ scope.game。

下面的代码显示了如何刷新$ scope.game。

function getGame(gameId, callback) { 
    gameService.getGame(gameId, function(err, data) { 
     if (!err) { 
      $scope.game = data; // Set game 

      if (callback) callback(data); 
     } 
    }); 
} 

在这一点上,视图基本上是冻结的。它完全停止响应玩家连接和断开连接。刷新浏览器或控制器可以解决问题。

我已经记录$ scope.game.players控制台,它似乎包含正确的连接状态。该视图根本没有回应。 我试图实现$范围。$ apply()以各种方式和地方,但所有给我的是'angular.js:13920错误:[$ rootScope:inprog] $应用已在进行中'。包装$范围。$适用()在$超时()摆脱上述错误的,但不解决问题。

花费数小时试图解决这一问题后,我可能有tunnelvision的情况。对任何能够帮助我的人都有无尽的荣誉。

编辑:刚刚实现所有套接字数据通过$ rootScope.apply()处理。 全码:

var socket = io.connect("http://localhost:8180/"); 
return { 
    on: function(eventName, callback) { 
     socket.on(eventName, function() { 
      var args = arguments; 
      $rootScope.$apply(function() { 
       callback.apply(socket, args); 
      }); 
     }); 
    }, 
    emit: function(eventName, data, callback) { 
     socket.emit(eventName, data, function() { 
      var args = arguments; 
      $rootScope.$apply(function() { 
       if (callback) { 
        callback.apply(socket, args); 
       } 
      }); 
     }) 
    }, 
    off: function(eventName) { 
     socket.off(eventName); 
    } 
}; 

现在,我更不知道该怎么做虽然..

回答

0

终于修好了...

我忘了我是在使用指令作为'玩家'。对于懒惰的原因,而不是创建一个孤立的范围,通过玩家的对象,我分配的选手对象范围按以下方式:

link: function(scope, elem, attrs) { 
     /* 
      Decided not to use an isolated scope because the 
      player directive needs access to the $rootScope. 
      The solution below eliminates the need of said scope. 
     */ 
     scope.player = scope.$eval(attrs.player); 

    } 

正如你看到的,甚至有评论解释我的愚蠢的决定。

0
if (!$scope.$$phase) { 
    $scope.game = data; // Set game 

    if (callback) callback(data); 
} 

这将触发一个摘要,如果一个不是目前正在进行中。否则,您的代码将被运行摘要更新。

+0

不幸的是,这个检查使得我的视图完全空了。没有要显示的数据。 – Daan

+0

日志中是否有任何错误 – Andonaeus

+0

没有错误。只是缺乏我的观点的回应。 – Daan