angularJS绑定等待input

我正在与Angular JS和Socket.io一起尝试开发一个简单的聊天室。 当没有插入sockets时,我的客户端工作得很好。 然后,我添加套接字通信后,绑定搞乱了。

我input消息并点击发送。 addMessage被触发,然后“聊天消息”套接字事件被触发。 但是,用户界面不会更新,直到我键入另一个字母或再次单击发送。 然后绑定起作用,用户界面添加消息。

有任何想法吗?

js文件

//Receive Socket message. //Runs but UI does not update. //UI updates on user's next input $scope.socket.on('chat message', function(msg) { var message = new Message(msg); $scope.messages.splice(0, 0, message); $scope.clear(); }); //Add Message, sends to socket $scope.addMessage = function () { if($scope.validate()) { var message = new Message($scope.message); $scope.socket.emit('chat message', message.text); } }; 

html文件

 <form role="form" ng-submit="addMessage()"> <div class="row"> <div class="input-group" style="margin-bottom: 5px;"> <input type="text" ng-model="message" placeholder="What's up?" class="form-control" ng-change="validate()"> <span class="input-group-btn"> <input type="submit" class="btn btn-primary" value="Add"/> </span> </input> </div> </div> </form> <div ui-sortable ng-model="messages"> <div ng-repeat="message in messages" style="padding:5px 10px;"> <p>{{ message.text }}</p> </p> </div> 

我可能会错过一些上下文,但是它看起来像是在Angular digest循环之外更新$scope ,通常是来自服务器调用或setTimeout的asynchronous代码块。

Angular没有意识到范围已经在asynchronous上下文中被更新了,直到下一个摘要循环(例如通过键盘input触发)才会刷新DOM。

为了强制Angular手动$scope.apply ,你需要调用$scope.apply ,或者是更新之后:

 $scope.socket.on('chat message', function(msg) { var message = new Message(msg); $scope.messages.splice(0, 0, message); $scope.clear(); $scope.apply(); }); 

或者像这样在callback中进行更新:

 $scope.socket.on('chat message', function(msg) { $scope.$apply(function() { var message = new Message(msg); $scope.messages.splice(0, 0, message); $scope.clear(); }); }); 

(好处是Angular将处理和委托任何抛出的错误)。

更新 :好吧,我只是意识到你正在使用一个自定义的$scope.socket事件发射器,我认为这是一个正常的$scope.$emit 。 所以干净的方法是直接在socket.emit函数中应用scope。 如果这是一个服务,你可以在这个服务中注入$rootScope ,并把这个发射包装在$rootScope.apply(...) 。 或使用$timeout 。 或者,如果它是一个完全没有angular度的东西,可以不要把它和angular度东西混淆起来,或者把它包装到一个angular度服务中,或者只要你需要的时候$apply你的范围(但这是最不干净的解决scheme)。