0

因为我想在 AngularJS 中实现聊天,所以我想使用 promise/deferred 原则。我的ChatService样子如下:

factory('ChatService', ['$q', '$resource', function($q, $resource) {

            var Service = {};
            var connected = false;
            var connection;

            var chatResource = $resource('/guitars/chat/:action', {action: '@action'}, {
                requestChatroomId: {
                    params: {
                        action: 'requestChatroomId'
                    },
                    method: 'GET'
                },
                sendMessage: {
                    params: {
                        action: 'sendMessage'
                    },
                    method: 'POST'
                }
            });

            Service.connect = function(cb) {

                var deferred = $q.defer();

                chatResource.requestChatroomId(function(data) {

                    connection = new WebSocket('ws://127.0.0.1:8888/realtime/' + data.chatroomId);

                    connection.onerror = function (error) {
                        deferred.reject('Error: ' + error);
                    };

                    connection.onmessage = function (e) {
                        cb.call(this, e.data);
                        deferred.notify(e.data);
                    };

                    connected = true;
                });

                return deferred.promise;
            };

            Service.sendMessage = function(msg) {
                if(!connected) {
                    return;
                }
                chatResource.sendMessage({message: msg});
            }

            return Service;
        }])

我使用 ChatService 的控制器是:

app.controller('ChatCtrl', ['$scope', 'ChatService', function($scope, ChatService) {
        $scope.chat = {};
        $scope.chat.conversation = [];

        var $messages = ChatService.connect(function(message) {
            $scope.$apply(function() {
                // #1 THIS FIRES EVERY TIME
                $scope.chat.conversation.push(message);
            });
        });

        $messages.then(function(message) {
            console.log('Finishes - should never occur!')
        }, function(error) {
            console.log('An error occurred!')
        }, function(message) {
            // #2 THIS FIRES ONLY IF THERE IS AN INTERACTION WITH THE ANGULAR MODEL
            console.log(message);
        });

        $scope.sendMessage = function(event) {
            ChatService.sendMessage($scope.chat.message);
            $scope.chat.message = '';
        };
    }]);

如果从服务器推送某些内容,则会调用回调#1,但不会调用回调#2,直到与角度模型发生一些交互,即开始在输入框中写入内容。这种行为的原因是什么?

4

1 回答 1

0

好吧,原因是 AngularJS 不知道发生了变化。所以我将 $rootScope 注入到我的ChatService

factory('ChatService', ['$q', '$resource', '$rootScope', function($q, $resource, $rootScope) {

我在connection.onmessage$rootScope 上调用了 $apply():

connection.onmessage = function (e) {
  deferred.notify(e.data);
  $rootScope.$apply();
};
于 2013-08-28T02:23:34.017 回答