设计两个 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(){
        ...
    };
});

我的问题是:

还有其他想法吗?

我的做法是,通常有一项服务负责与 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来处理错误,通常在范围内设置一个临时变量,表示凭据错误。