我正在使用UI-Router作为Angular应用程序。我有通过用于创建排序连接对象的异步调用$http
来获取数据。我的目标是创建这个对象并将其作为单例提供。虽然发生这种情况的可能性很少,但我期望避免在服务的socket
属性异步分配时发生时间问题。当路由器中的另一个状态想要获取或创建另一个连接对象时,它将通过单例执行此操作,以便可以使用相同的连接而不是创建另一个连接。角度服务异步单身UI-Router
下面是一些代码的框架,我试图去工作。我不确定是否可以用国家的resolve
做些事情。
有关如何做到这一点的任何想法或建议?
var myapp = angular.module('me', ['ui.router'])
.service('connectionService', ['$http', function($http) {
var socket;
// Somehow call and store result of $http in a singleton
// Would the $http.get get put in some kind of function? If so, how should it get called
// and returned so that a user of the service can get the 'socket' object synchronously?
$http.get("something/that/returns/data")
.success(function (result) {
this.socket= createConnection(result.data);
})
.error(function (err) {
//handle error
})
var getSocket= function() {
if (!this.socket) {
return createNewSocket();
} else {
return this.socket;
}
}
}])
myapp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("home");
$stateProvider
.state('home', {
url: "/home",
templateUrl: "home.html",
resolve: {
socket: // ??? Can something be done here ???
},
controller: function(socket) {
// I can haz socket?
}
})
.state('nextState', {
url: "/next",
templateUrl: "next.html",
resolve: {
socket: // Should be the same socket object as from the home state
},
controller: function(socket) {
// I can haz same socket?
}
})
})
更新
在试图更好地解释这个问题的过程中,我已经改变了原来的代码几次。人们留下的评论改正了我的错误。我已经将上面的代码恢复到了原来的样子,并在下面添加了新的代码。我仍然存在的问题是在进入控制器之前,ui-router状态下的resolve
未被解析。因此,在socket
对象上调用emit()
时,我认为“Can not read property”的错误会导致“undefined”。我还希望socket
对象成为这些状态之间的相同对象。我将不胜感激任何其他建议或意见,以引导我朝着正确的方向前进。
var myapp = angular.module('me', ['ui.router'])
.service('connectionService', ['$http', function($http) {
var socket;
// Somehow call and store result of $http in a singleton
// Would the $http.get get put in some kind of function? If so, how should it get called
// and returned so that a user of the service can get the 'socket' object synchronously?
$http.get("something/that/returns/data")
.then(function (result) {
socket = createConnection(result.data);
}, function (err) {
// handle error
});
var getSocket = function() {
if (!socket) {
// handle error
} else {
return socket;
}
}
}])
myapp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("home");
$stateProvider
.state('home', {
url: "/home",
templateUrl: "home.html",
resolve: {
socket: function(connectionService) {
return connectionService.getSocket();
}
},
controller: function(socket) {
socket.emit("some msg");
}
})
.state('nextState', {
url: "/next",
templateUrl: "next.html",
resolve: {
socket: function(connectionService) {
return connectionService.getSocket();
}
},
controller: function(socket) {
socket.emit("some other msg");
}
})
})
更新2
工作的解决方案,但是这是已被接受为正确的答案不一样优雅的Muli Yulzari的答案。
我研究了创建自己的承诺并将其作为ui-router解决的问题返回。根据我的所有调试和堆栈跟踪,在这些状态之间只有一个连接被创建,并且进入控制器的时间被延迟直到连接被解决。所以,我相信这是一个可行的解决方案。在解决承诺之前,我还有一个处理连接事件的代码版本,但为了简洁起见,我已将其忽略。
var myapp = angular.module('me', ['ui.router'])
.service('connectionService', ['$http', '$q', function($http, $q) {
var socket;
this.getSocket = function() {
if (!socket) {
var deferred = $q.defer();
$http.get("something/that/returns/data")
.then(function (result) {
socket = createConnection(result.data);
deferred.resolve(socket);
}, function (err) {
// handle error
deferred.reject(socket);
});
return deferred.promise;
} else {
return socket;
}
}
}])
myapp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("home");
$stateProvider
.state('home', {
url: "/home",
templateUrl: "home.html",
resolve: {
socket: function(connectionService) {
return connectionService.getSocket();
}
},
controller: function(socket) {
socket.emit("some msg");
}
})
.state('nextState', {
url: "/next",
templateUrl: "next.html",
resolve: {
socket: function(connectionService) {
return connectionService.getSocket();
}
},
controller: function(socket) {
socket.emit("some other msg");
}
})
})
在角度上,服务是单身,所以这确实是你想要的。但是,您的服务构建方式存在一些问题;具体而言,在回调中使用'.this'将不会按照您的意图工作,因为'.this'指的是回调,而不是父服务。另外,你应该考虑切换到'.then'而不是弃用的'.success'。 – Claies
删除不推荐的'.success'并切换到'。然后'承诺。 – BoJoe22
你仍然在承诺中使用'.this',这是不起作用的主要部分。 – Claies