angularjs服务器请求的视觉反馈

时间:2013-10-14 08:54:23

标签: http angularjs

如何通过角度方式向用户显示appp正在等待来自服务器的答案?

目前我的工厂有以下代码

app.factory('MyAppFact', ['$http', '$q', 
function($http, $q) {
    function _success(data, status) {
        document.body.classList.remove('waitserver')
        if (data.status == 'OK') {
            this.resolve(data);
        } else {
            this.reject(data);
        }   
    }
    function _error(data, status) {
        document.body.classList.remove('waitserver')
        this.reject(status})    
    }
    return {
        changeLocale: function(locale){
            var d = $q.defer();
            document.body.classList.add('waitserver');
            $http.get('/changeLocale/'+locale).success(_success.bind(d), 
                _error.bind(d));
            return d.promise;
        },
        login: function(uname, passwd, keep) {
            var d = $q.defer();
            document.body.classList.add('waitserver');
            $http.post('/login', {uname:uname, passwd:passwd, keep:keep}
                ).success(_success.bind(d), _error.bind(d));
            return deferred.promise;
        },
        register: function(user) {
            var d = $q.defer();
            document.body.classList.add('waitserver');
            $http.post('/register', {user:user}).success(_success.bind(d), 
                _error.bind(d));
            return deferred.promise;
        },

        ...

    }
}]);

虽然这段代码有效,但是我在文档体中添加了一个css类,而根据angularjs文档,我不应该在工厂方法中更改DOM,从而违反了MVC的明确分离

但我不知道在这种情况下如何完成分离。

1 个答案:

答案 0 :(得分:0)

您可以组合一些全局状态,ng-class指令(应用于<body>或动态Angular托管内容的包装元素)和描述here的HTTP拦截器。

因此,全局状态类似于活动请求计数器,作为服务实现或$rootScope的成员。让我们考虑第二个是为了简单,虽然第一个似乎更正确:

$rootScope.activeRequestsCounter = 0;

您注册操纵计数器的拦截器:

$provide.factory('myHttpInterceptor', function($rootScope) {
    function increase() {
        $rootScope.activeRequestsCounter++;
    }

    function decrease() {
        $rootScope.activeRequestsCounter--;
    }

    return {
        request: increase,
        requestError: decrease,
        response: decrease,
        responseError: decrease
    };
});


// in some config block:
$httpProvider.interceptors.push('myHttpInterceptor');

在HTML中:

<body ng-class="{waitserver: activeRequestsCounter &gt; 0}">

这是操作原理,细节可能需要细化。您获得的是您不再需要担心在每个服务调用中添加/删除类。您可以调用多个服务,计数器将正确更新。而且你不会在服务中操纵DOM(更干净的代码)。