AngularJS:从服务中删除$ rootScope

时间:2014-02-05 15:39:23

标签: angularjs angularjs-scope angularjs-service angularjs-controller

我有一个围绕WebSocket的服务,我想用promises和请求与响应耦合,这是我想出的:

(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?我甚至不确定我是否应该摆脱它,如果惯例说我应该,如何处理它。感谢

1 个答案:

答案 0 :(得分:2)

  

我被告知服务不应该在任何范围内运行。

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

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

供参考,请参阅内置的$http服务。这包裹XMLHttpRequest类似于你如何包装网络套接字,它取决于$rootScope,因为你的代码完全取决于$rootScope的功能。

您的代码演示了在服务中使用$rootScope的规范。