AngularJS:从服务中删除$rootScope
我有一个围绕WebSocket的服务,我想通过承诺和将请求与响应结合起来来实现,下面是我的想法: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
(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,没有它,一切似乎都很好,奇怪吗?