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

|▌冷眼眸甩不掉的悲伤 提交于 2020-01-07 04:56:08

问题


I have sockets working, in that each client seems to be running the proper code block that console.logs the event. 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.

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.

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>


回答1:


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.

$scope.$apply() lets angular know that data has updated, and to refresh what needs to be refreshed.

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]);             
        });
    });
}]);



回答2:


Following code work for me, Whenever you get message from socket you just need to bind your code inside $scope.$apply() function

 socket.onmessage = function (e) {

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

        };


来源:https://stackoverflow.com/questions/28722737/angular-js-socket-io-event-updates-model-not-view

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!