繁体   English   中英

编写惰性Ajax服务的最佳实践

[英]Best practices to write lazy ajax services

在angular-js中编写惰性Ajax服务的最佳实践是什么? 例如,我想要创建出于某种原因应该返回promise的资源:

angular.module('MyModule',[])
  .factory('myService', function() {
    return {
      getData: function() {
          return $http.get('http://host/api/data');
      }
    }
  });

而且我只想加载一次数据,那么实现它的最佳方法是什么? 我只有一个主意,这真的很丑:

angular.module('MyModule', [])
.factory('myService', function($q) {
    var dataResponse = null;
    return {
        getData: function() {
            if (dataResponse) {
                var def = $q.defer();
                def.resolve(dataResponse);
                return def.promise;
            }
            return $http.get('http://host/api/data');
        },
        setDataResponse: function(response) {
            dataResponse = response;
        }
    }
})
.controller('MyCtrl', function($scope, myService) {
    myService.getData().then(function(response) {
        myService.setDataResponse(response);
        $scope.data = response.data
    })
});

我不喜欢这部分:

var def = $q.defer();
def.resolve(dataResponse);
return def.promise;

而且我也不喜欢每次调用getter都必须编写响应设置器这一事实,但是我真的不知道如何使此代码更好。

由于您不喜欢这一部分:

var def = $q.defer();
def.resolve(dataResponse);
return def.promise;

将其重写为:

return $q.resolve(dataResponse);

并不是说在AngularJS <1.4中,resolve方法被称为when()。

您可以通过在解析前在“ getData”方法中将结果内部缓存在服务中来修复代码的其余部分。 那不应该是呼叫者的责任。 所以:

return {
    getData: function() {
        if (dataResponse !== null) {
            return $q.resolve(dataResponse);
        }

        return $http.get('http://host/api/data').then(onSuccess);

        function onSuccess(data){
            dataResponse = data;
            return data;
        }
    }
}

您可以稍微整理一下记忆逻辑。

angular.module('MyModule', [])
.factory('myService', function($q) {
    var dataResponse = null;
    return {
        getData: function() {
            if (dataResponse) {
                return $q.when(dataResponse); // or $q.resolve for angular 1.4+
            }
            return $http.get('http://host/api/data').then(function(data) {
              dataResponse = data;
              return data;
            });
        },
    }
})
.controller('MyCtrl', function($scope, myService) {
    // use as normal. No need to write back
    myService.getData().then(function(response) {
        $scope.data = response.data
    })
});

您应该使用$ resource ,它有一个选项可以简单地缓存数据,并且更容易绑定到RESTapi。

否则,您可以自己简单地缓存数据:

angular.module('MyModule', [])
.factory('MyService', function($q) {
    var dataResponse;
    return {
        getData: function() {
            return $q(function(resolve, reject) {
                if(angular.isDefined(dataResponse)) {
                    resolve(dataResponse);
                } else {
                    $http
                        .get('http://host/api/data')
                        .then(function(response) {
                            dataResponse = response;
                            resolve(dataResponse);    
                        });
                }
            });
            if (dataResponse) {
                var def = $q.defer();
                def.resolve(dataResponse);
                return def.promise;
            }
            return $http.get('http://host/api/data');
        },
        setDataResponse: function(response) {
            dataResponse = response;
        }
    }
})
.controller('MyCtrl', function($scope, MyService) {
    MyService
        .getData()
        .then(function(response) {
            var vm = this;
            vm.data = response.data
        })
});

现在请注意,我将数据绑定到了控制器(ViewModel的虚拟机),因此您应该将模板重构为以下形式:

<ul ng-controller="MyCtrl as ctrl">
    <li ng-repeat="item in ctrl.data">
        {{ item.name }}: {{ item.price }}
    </li>
</ul>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM