设计两个 AngularJS 服务之间的关系,用于登录和 API
Design relationship between two AngularJS services, for Login and for API
这更像是一个设计问题:
我有一个 angularJS 应用程序,
此应用程序使用服务与具有登录功能的 API 通信...
app.service('managerApiService', function($q){
var myApi = new WWW_Wrapper(...);
myApi.setInput('www-asynchronous', true);
var defer = $q.defer();
this.login = function(){
...
};
this.logout = function(){
...
};
this.getShops = function(){
...
return defer.promise;
}
});
和另一个处理用户 Login/Credentials/Info:
的服务
app.service('loginService', function(){
this.credentials = {username: null, password: null };
this.loginData = null; // comes from server during login...
this.login = function(){
...
};
this.logout = function(){
...
};
});
我的问题是:
- 我的
LoginService
应该注入 managerApiService
并更新它的凭据吗?
- 我的
managerApiService
应该注入 LoginService
并观察它的凭据吗?
- 我应该将它们合并为一项服务吗?
还有其他想法吗?
我的做法是,通常有一项服务负责与 API 通信但不关心状态。它只关心创建请求和 returning 结果。然后,我有另一个服务负责会话,这个服务处理状态(用户名、密码等)。此服务(会话)注入 API 服务,并调用它的方法。然而,API 永远不知道此服务器的存在。
更详细地说,我通常有一个服务负责与后端通信(我假设这类似于您的 managerApiService)。像这样:
app.service('managerApiService', [ '$q', function ( $q ) {
this.login = function ( credentials ) {
// ...
};
this.logout = function () {
// ...
};
} ] );
请注意,此服务不存储任何与登录或会话相关的信息。
然后我使用另一个负责维护会话的服务,这意味着它存储当前的用户标识、用户信息、权限或其他任何必要的东西。该服务将实际执行登录的任务委托给之前的服务,它可能看起来像这样
app.service('loginService', [ 'managerApiService', function ( managerApiService ) {
this.loginData = null;
this.login = function ( credentials ) {
return managerApiService.login( credentials ).then( /* ... */ );
};
this.logout = function () {
...
};
} ] );
主要优点是什么:由于与服务器的通信是抽象的,您可以更改服务器的工作方式,只需更新 API 服务。或者您甚至可以添加新的登录提供程序,而您的应用程序甚至不需要知道。 API 将负责提出适当的请求。
基本上,您的方向是正确的。我要做的唯一区别是不将凭据存储在 LoginService 上,而是将它们存储在视图或控制器上。这是因为 LoginService 在整个应用程序中保持活动状态,而不仅仅是登录屏幕,并且在执行登录后无需将凭据存储在内存中。
至于错误,我让服务器return一个错误代码,比如400,或者401。然后在控制器上,我通常监听一个.catch
来处理错误,通常在范围内设置一个临时变量,表示凭据错误。
这更像是一个设计问题:
我有一个 angularJS 应用程序,
此应用程序使用服务与具有登录功能的 API 通信...
app.service('managerApiService', function($q){
var myApi = new WWW_Wrapper(...);
myApi.setInput('www-asynchronous', true);
var defer = $q.defer();
this.login = function(){
...
};
this.logout = function(){
...
};
this.getShops = function(){
...
return defer.promise;
}
});
和另一个处理用户 Login/Credentials/Info:
的服务app.service('loginService', function(){
this.credentials = {username: null, password: null };
this.loginData = null; // comes from server during login...
this.login = function(){
...
};
this.logout = function(){
...
};
});
我的问题是:
- 我的
LoginService
应该注入managerApiService
并更新它的凭据吗? - 我的
managerApiService
应该注入LoginService
并观察它的凭据吗? - 我应该将它们合并为一项服务吗?
还有其他想法吗?
我的做法是,通常有一项服务负责与 API 通信但不关心状态。它只关心创建请求和 returning 结果。然后,我有另一个服务负责会话,这个服务处理状态(用户名、密码等)。此服务(会话)注入 API 服务,并调用它的方法。然而,API 永远不知道此服务器的存在。
更详细地说,我通常有一个服务负责与后端通信(我假设这类似于您的 managerApiService)。像这样:
app.service('managerApiService', [ '$q', function ( $q ) {
this.login = function ( credentials ) {
// ...
};
this.logout = function () {
// ...
};
} ] );
请注意,此服务不存储任何与登录或会话相关的信息。
然后我使用另一个负责维护会话的服务,这意味着它存储当前的用户标识、用户信息、权限或其他任何必要的东西。该服务将实际执行登录的任务委托给之前的服务,它可能看起来像这样
app.service('loginService', [ 'managerApiService', function ( managerApiService ) {
this.loginData = null;
this.login = function ( credentials ) {
return managerApiService.login( credentials ).then( /* ... */ );
};
this.logout = function () {
...
};
} ] );
主要优点是什么:由于与服务器的通信是抽象的,您可以更改服务器的工作方式,只需更新 API 服务。或者您甚至可以添加新的登录提供程序,而您的应用程序甚至不需要知道。 API 将负责提出适当的请求。
基本上,您的方向是正确的。我要做的唯一区别是不将凭据存储在 LoginService 上,而是将它们存储在视图或控制器上。这是因为 LoginService 在整个应用程序中保持活动状态,而不仅仅是登录屏幕,并且在执行登录后无需将凭据存储在内存中。
至于错误,我让服务器return一个错误代码,比如400,或者401。然后在控制器上,我通常监听一个.catch
来处理错误,通常在范围内设置一个临时变量,表示凭据错误。