简体   繁体   English

Angular.js-Socket.io事件更新模型,而非视图

[英]Angular.js - Socket.io event updates model, not view

I have sockets working, in that each client seems to be running the proper code block that console.logs the event. 我有套接字工作,因为每个客户端似乎正在运行console.logs事件的正确代码块。 The client that sends the message updates the view, but the other connected clients don't. 发送消息的客户端会更新视图,而其他已连接的客户端则不会。

But when another client sends a message, its view updates with all the backlogged messages that it's been pushing to the model, so I know that part is working. 但是,当另一个客户端发送一条消息时,它的视图将使用它一直推送到模型的所有积压消息进行更新,因此我知道该部分正在工作。 It's just the view that's not updating. 只是视图没有更新。

I've done some reading, and it looks like I need to refactor my code to use $scope and $scope.$apply , but I'm not sure how. 我已经读了一些书,看起来我需要重构代码以使用$scope$scope.$apply ,但是我不确定如何。

app.controller('StoryController', ['$http', '$scope', function($http, $scope){
    var story = this;

    socket.on('new storyPoint', function(msg){
        //console.log('new storyPoint!', msg);
        story.points.push(msg);
        $('.story').scrollTop($('.story')[0].scrollHeight);
        console.log('last story point:', story.points[story.points.length - 1]);
    });
}]);

As you can see, I'm not actually using $scope yet, and I'm pretty sure I need to, but trying to mimic other solutions to this problem has failed. 如您所见,我实际上还没有使用$scope ,而且我敢肯定我需要使用$scope ,但是尝试模仿该问题的其他解决方案失败了。

Edit: And here's the view: 编辑:这是视图:

<div class="container story-container" ng-controller="StoryController as storyCtrl">
<aside class="players" id="players"><h1>Players </h1>
    <input name="username" type="text" ng-model="storyCtrl.username"/>
    <ul class="players-list">
        <li>{{storyCtrl.username}}</li>
        <li ng-repeat="player in game.settings.players">{{player}}</li>
    </ul>
</aside>
<div class="main">
    <h1 class="story-title">{{game.settings.title}}</h1>
    <ul class="story">
        <li ng-repeat="storyPoint in storyCtrl.points"><p>{{storyPoint.body}}</p></li>
        <li><p>{{storyCtrl.point.body}}</p></li>
    </ul>
    <form name="storyForm" ng-submit="storyCtrl.addPoint(storyCtrl)">
        <textarea ng-model="storyCtrl.point.body" name="storyPoint" rows="5"></textarea>
        <input class="btn btn-success" type="submit"/>
    </form>
</div>

The issue is that Socket.io does not live inside the angular lifecycle, and thus Angular doesn't know new data has come in. You're right that you need to inject $scope into your controller, and the perform a $scope.$apply() inside your socket.io callback, as the last action. 问题在于Socket.io不在角生命周期内,因此Angular不知道有新数据传入。您是对的,需要将$scope注入到控制器中,然后执行$scope.$apply() socket.io回调中的$scope.$apply()作为最后一个动作。

$scope.$apply() lets angular know that data has updated, and to refresh what needs to be refreshed. $scope.$apply()让angular知道数据已更新,并刷新需要刷新的内容。

app.controller('StoryController', ['$http', '$scope', function($http, $scope){
    var story = this;

    socket.on('new storyPoint', function(msg){
        //console.log('new storyPoint!', msg);            
        $scope.$apply(function(){
            story.points.push(msg);
            $('.story').scrollTop($('.story')[0].scrollHeight);
            console.log('last story point:', story.points[story.points.length - 1]);             
        });
    });
}]);

Following code work for me, Whenever you get message from socket you just need to bind your code inside $scope.$apply() function 以下代码为我工作,每当您从套接字收到消息时,只需要将代码绑定到$ scope。$ apply()函数中

 socket.onmessage = function (e) {

            $scope.$apply(function () {
                $scope.onMessge(e);
            });

        };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM