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 を my に注入しました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 に答える