我正在使用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