我正在使用 Angular JS 和 Socket.io 尝试开发一个简单的聊天室。当未插入套接字时,我让客户端工作得很好。然而,在我添加套接字通信后,绑定(bind)就变得困惑了。
我输入消息并点击发送。 addMessage 被触发,然后“聊天消息”套接字事件被触发。但是,直到我输入另一个字母或再次单击“发送”后,用户界面才会更新。然后绑定(bind)发挥其魔力,UI 添加消息。
有什么想法吗?
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>
最佳答案
我可能会错过一些上下文,但看起来您正在更新您的 $scope
在 Angular 摘要周期之外,通常位于来自服务器调用或 setTimeout
的异步代码块中例如。
Angular 不知道作用域已在此类异步上下文中更新,并且直到下一个摘要周期(例如在您的情况下由某些键盘输入触发)才会刷新 DOM。
为了强制Angular手动消化,你需要调用$scope.apply
,或者更新后的样子:
$scope.socket.on('chat message', function(msg) {
var message = new Message(msg);
$scope.messages.splice(0, 0, message);
$scope.clear();
$scope.apply();
});
或者通过在回调中进行更新,如下所示:
$scope.socket.on('chat message', function(msg) {
$scope.$apply(function() {
var message = new Message(msg);
$scope.messages.splice(0, 0, message);
$scope.clear();
});
});
(优点是 Angular 将处理和委托(delegate)抛出的任何错误)。
更新:好的,我刚刚意识到您正在使用自定义 $scope.socket
事件发射器,我以为这是一个常规的$scope.$emit
第一次阅读时。因此,最干净的方法是直接在 socket.emit
内应用范围。功能。如果这是一个服务,你可以注入(inject)$rootScope
在此服务中并将发射包装在 $rootScope.apply(...)
中。或者使用$timeout
。或者,如果它是一个完全没 Angular 东西,那么不要将它与 Angular 东西搞乱,或者将其包装到 Angular 服务中,或者简单地 $apply
就可以了。您可以在需要时随时使用您的范围(但这是最不干净的解决方案)。
关于javascript - Angular JS 绑定(bind)等待输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30064567/