AngularJS服务存储$ http结果以防止重新生成---有更好的方法吗?

RVC*_*RVC 7 angularjs angular-http angular-services

设置:我希望有一个服务,多个控制器可以查询使用$ http提取的数据.最初的解决方案是使用此处建议的promises .

问题:每次控制器查询服务时,服务都会返回$ http保证,从而导致多次查询只是从远程服务器中反复提取相同的数据.

解决方案:服务函数返回数据或下面的承诺.并由控制器进行相应的检查和操作.

app.factory('myService', function($http) {
    var items = [];
    var myService = {
        getItems: function() {
            // if items has content, return items; otherwise, return promise.
            if (items.length > 0) {
                return items;
            } else {     
                var promise = $http.get('test.json').then(function (response) {
                    // fill up items with result, so next query just returns items.
                    for(var i=0;i<response.data.length;i++){
                        items.push(response.data[i]);
                    }
                    return items;
                });
                // Return the promise to the controller
                return promise;
            }
     };
     return myService;
});
Run Code Online (Sandbox Code Playgroud)

因此,当控制器需要该数据时,控制器只需执行以下操作:

app.controller('MainCtrl', function( myService,$scope) {
    var promiseOrData = myService.async();
    // Check whether result is a promise or data.
    if ( typeof promiseOrData.then === 'function'){
        // It's a promise.  Use then().
        promiseOrData.then( function(data ){
            $scope.data = data;
        });
    } else {
        // It's data.
        $scope.data = data;
    }
});
Run Code Online (Sandbox Code Playgroud)

所以问题是:有更好的方法吗?对于许多控制器,这种方法会有很多重复的代码.理想情况下,控制器只是直接查询服务数据.

谢谢!

Mar*_*cok 12

$ http返回一个promise,我们可以使用它而不是用$ q创建一个新的.一旦承诺得到解决,我们就可以继续回复.

.factory('myService', ['$http','$q', function($http, $q) {
    var items = [];
    var last_request_failed = true;
    var promise = undefined;
    return {
        getItems: function() {
            if(!promise || last_request_failed) {
                promise = $http.get('test.json').then(
                function(response) {
                    last_request_failed = false;
                    items = response.data;
                    return items;
                },function(response) {  // error
                    last_request_failed = true;
                    return $q.reject(response);
                });
            }
            return promise;
        },
    };
}])
Run Code Online (Sandbox Code Playgroud)

在你的控制器中:

myService.getItems().then( 
    function(data) { $scope.data = data; }
);
Run Code Online (Sandbox Code Playgroud)