AngularJS:从服务中删除$rootScope

AngularJS:从服务中删除$rootScope,angularjs,angularjs-scope,angularjs-service,angularjs-controller,Angularjs,Angularjs Scope,Angularjs Service,Angularjs Controller,我有一个围绕WebSocket的服务,我想通过承诺和将请求与响应结合起来来实现,下面是我的想法: (function () { var app = angular.module('mainModule'); app.service('$wsService', ['$q', '$rootScope', '$window', function($q, $rootScope, $window) { var self = this; // Keep all pending req

我有一个围绕WebSocket的服务,我想通过承诺和将请求与响应结合起来来实现,下面是我的想法:

(function () {

var app = angular.module('mainModule');

app.service('$wsService', ['$q', '$rootScope', '$window', function($q, $rootScope, $window) {

    var self = this;

    // Keep all pending requests here until they get responses
    var callbacks = {};
    // Create a unique callback ID to map requests to responses
    var currentCallbackId = 0;

    var ws = new WebSocket("ws://127.0.0.1:9090");
    this.webSocket = ws;

    ws.onopen = function(){
        $window.console.log("WS SERVICE: connected");
    };

    ws.onmessage = function(message) {
        listener(JSON.parse(message.data));
    };

    var listener = function (messageObj) {
        // If an object exists with callback_id in our callbacks object, resolve it
        if(callbacks.hasOwnProperty(messageObj.Request.ID)) {
            $rootScope.$apply(
                callbacks[messageObj.Request.ID].cb.resolve(messageObj));
            delete callbacks[messageObj.Request.ID];
        }
    };

    // This creates a new callback ID for a request
    var getCallbackId = function () {
        currentCallbackId += 1;
        if(currentCallbackId > 10000) {
            currentCallbackId = 0;
        }
        return currentCallbackId;
    };

    //sends a request
    var sendRequest = function (request, callback) {
        var defer = $q.defer();
        var callbackId = getCallbackId();
        callbacks[callbackId] = {
            time: new Date(),
            cb:defer
        };
        request.ID = callbackId;

        $window.console.log("WS SERVICE: sending " + JSON.stringify(request));
        ws.send(JSON.stringify(request));

        if(typeof callback === 'function') {
            defer.promise.then(function(data) {
                callback(null, data);
            },
            function(error) {
                callback(error, null);
            });
        }
        return defer.promise;
    }; 

    this.exampleCommand = function(someObject, callback){
        var promise = sendRequest(someObject, callback);
        return promise;
    };
}]);

}());
我在控制器中使用它,如下所示:

(function () {
'use strict';

var app = angular.module('mainModule');

app.controller('someController', ['$scope', '$wsService', function ($scope, $wsService) {

    $scope.doSomething = function(){
        $wsService.exampleCommand(
            {/*some data for the request here*/},
            function(error, message){
                //do something with the response
            }
        );    
    };

}]);

}());
在实现这一点之后,我被告知该服务不应该在任何类型的范围内运行。所以我的问题是-我将如何从服务中删除$rootScope?我甚至不知道我是否应该摆脱它,如果惯例说我应该,如何处理它。谢谢

有人告诉我,这项服务不应真正在任何范围内运作

谁告诉你的?这是完全错误的

您的服务正在接收来自websocket的摘要周期之外的回调。要使用angular,这些更新需要在摘要周期内应用-这正是您正在做的

有关参考信息,请参阅内置的
$http
服务。它将
XMLHttpRequest
包装为类似于您包装web套接字的方式,它取决于
$rootScope
的功能,而您的代码恰恰依赖于
$rootScope
的功能


您的代码演示了
$rootScope
在服务内部的规范用法。

您是否可以使用发布/订阅服务在该服务和控制器(以及范围)之间进行通信?这是我们最初的功能,控制器将订阅服务以接收传入消息等。它工作正常,但后来决定应该这样做,并打算在不久的将来将其重写为$http而不是websocket(这只是一个一次性/有限重用的原型),我明白了。。。我不得不面对一个类似的问题,我开发了一个有棱角的酒吧/酒吧服务。如果可以帮助您,请访问以下网站:。否则,我不确定是否只有一种正确的解决方案或模式可供使用。请看一看,如果您需要从更多控制器中访问服务,只需控制器中的一个shorcut。extend($scope,MyService);谢谢你的解释。既然我已经发布了代码,我就删除了$rootScope.$apply,没有它,一切似乎都很好,奇怪吗?