角度递归工厂方法

时间:2015-03-16 15:40:38

标签: angularjs recursion factory

我想问一下是否有可能返回递归工厂方法。我将展示一些代码,以便您更了解我。 我们有工厂:

angular.module('module')
.factory('synchronizationStatus', ['$http', 'apiBase', '$timeout', function ($http, apiBase, $timeout) {
    var service_url = apiBase.url;

    function syncCompleted ( correlationId ) {
        checkSync (correlationId)
            .then(function(response){
                $timeout(function() {
                    // if I get response.data true, i want to proceed to controller
                    if(response.data){
                        return "now I want to return result to controller"
                    }
                    else {
                        // check again
                        checkSync(correlationId)
                    }
                }, 500);

            })
    }

    function checkSync( correlationId ){
        return $http.get(service_url + query);
    }

    return {
        syncCompleted: syncCompleted
    };
}]);

这种工厂方法的主要思想是我经常(每个500ms)向后端发送ajax请求并检查某些操作是否完成,以及何时完成我想向控制器功能发送承诺,看起来像这样:

function save( client ) {
        clients.addClient( client )
            .then( function(response) {
              synchronizationStatus.syncCompleted(response.data.CorrelationId);
            }, onSaveError)
            .then( redirectToList, onSaveError )
            .finally( unblock );
    }

在backend返回true后我的工厂方法我想在我的控制器中执行其他功能。当然我可以在我的控制器中进行递归,它可以解决这个问题。虽然我必须在许多其他控制器中重用这个递归,所以我想重用这个方法。

2 个答案:

答案 0 :(得分:2)

是的,您应该可以这样做,但您需要稍微更改工厂中的代码:

angular.module('module')
.factory('synchronizationStatus', [
    '$http', 
    'apiBase', 
    '$timeout', 
    function ($http, apiBase, $timeout) {
        var service_url = apiBase.url;

        function waitSyncCompletion( correlationId ) {
            return checkSync (correlationId)
            .then(function(response){
                 if (response.data) {
                     return "all done!";
                 }   

                 return $timeout(function() {
                     // check again
                     return waitSyncCompletion(correlationId);
                 }, 500);
            });
        }

        function checkSync( correlationId ){
            var query = '...'; // determine query
            return $http.get(service_url + query);
        }

        return {
            waitSyncCompletion: waitSyncCompletion
        };
    }
]);

然后在您的控制器中,您需要使用return,以便等待操作完成:

function save( client ) {
    clients.addClient( client )
    .then( function(response) {
         return synchronizationStatus.waitSyncCompletion(response.data.CorrelationId);
    })
    .then(function (result) { console.log(result); })
    .then( redirectToList )
    .catch( onSaveError )
    .finally( unblock );
}

答案 1 :(得分:-1)

使用Angular的$q来使用自定义延迟(承诺)。确保在工厂中注入$q依赖项并在工厂开始时创建延迟:

var deferred = $q.defer()

在承诺必须解决的位置,添加:

deferred.resolve();

并确保在syncCompleted函数底部返回承诺:

return deferred.promise;

此外,如果您还想要错误处理,可以添加deferred.reject()。此外,如果需要,您可以向reject()resolve()添加参数。

作为替代方案,您可以在不使用$q的情况下实现相同的目标。 $timeout()也会返回一个承诺,如果你在给then()的回调函数中返回一个承诺,它将会'替换''父'承诺。